diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..522fac32 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Factorio-luacheckrc"] + path = Factorio-luacheckrc + url = https://github.com/Nexela/Factorio-luacheckrc diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..2e87afff --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,31 @@ +{ + "cSpell.enabledLanguageIds": [ + "asciidoc", + "c", + "cpp", + "csharp", + "css", + "go", + "handlebars", + "html", + "jade", + "javascript", + "javascriptreact", + "json", + "latex", + "less", + "lua", + "markdown", + "php", + "plaintext", + "pub", + "python", + "restructuredtext", + "rust", + "scss", + "text", + "typescript", + "typescriptreact", + "yml" + ] +} \ No newline at end of file diff --git a/Addons/load.lua b/Addons/load.lua deleted file mode 100644 index f5e4f41d..00000000 --- a/Addons/load.lua +++ /dev/null @@ -1,49 +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----------------------------------------------------------- --- This file just contains all the diffrent requires - --- Admin dir -verbose('Begain Admin Loading') -require('Admin/player-info') -require('Admin/admin') -- Used with Guis/admin-gui, but can work without -require('Admin/reports') -- This adds onto Admin/admin, adds report command and warnings, and temp ban -require('Admin/discord') -require('Admin/auto-message') -require('Admin/tree-decon') -require('Admin/inventory-search') -require('Admin/base-damage') -require('Admin/afk-kick') -require('Admin/auto-chat') - --- Commands dir -verbose('Begain Command Loading') -require('Commands/cheat-mode') -require('Commands/kill') -require('Commands/repair') -require('Commands/bonus') -require('Commands/tags') -require('Commands/home') -require('Commands/tp') -- Requires Admin/admin -require('Commands/admin') -- Requires Admin/reports - --- GUIs dir -verbose('Begain Gui Loading') -require('Guis/readme') -require('Guis/science') -require('Guis/rockets') -require('Guis/player-list') -require('Guis/tasklist') -require('Guis/warp-system') -require('Guis/polls') -- Too many desyncs -require('Guis/announcements') -require('Guis/rank-changer') -require('Guis/admin-gui') -- Used with Admin/admin, requires Admin/admin -require('Guis/reports') -- Requires Admin/reports -require('Guis/game-settings') \ No newline at end of file diff --git a/Addons/playerRanks.lua b/Addons/playerRanks.lua deleted file mode 100644 index dd5216d2..00000000 --- a/Addons/playerRanks.lua +++ /dev/null @@ -1,307 +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 reference 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 Assigned by the script to show the highest rank in this group. -lowest Assigned by the script to show the lowest rank in this group. -How to add ranks: -Name What will be used in the scripts and is often the best choice for display in text. -short_hand What can be used when short on space but the rank still need to be displayed. -tag The tag the player will gain when moved to the rank, it can be nil. -time Used for auto-rank feature where you are moved to the rank after a certain play time in minutes. -colour The RGB value that can be used to emphasise GUI elements based on rank. -power Assigned by the script based on their index in ranks, you can insert new ranks between current ones. -group Assigned by the script to show the group this rank is in. -disallow A list containing input actions that the user can not perform. -allow A list of custom commands and effects that that rank can use, all defined in the scripts. - -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. - -Ranking._group:create{ - name='Donator', - allow={}, - disallow={ - 'set_allow_commands', - 'edit_permission_group', - 'delete_permission_group', - 'add_permission_group' - } -} - -local groups = Ranking._groups(true) - -groups['Root']:edit('allow',false,{ - ['player-list']=true, - ['readme']=true, - ['rockets']=true, - ['science']=true, - ['tasklist']=true, - ['rank-changer']=true, - ['admin-commands']=true, - ['warn']=true, - ['temp-ban']=true, - ['clear-warings']=true, - ['clear-reports']=true, - ['clear-all']=true, - ['clear-inv']=true, - ['announcements']=true, - ['warp-list']=true, - ['polls']=true, - ['admin-items']=true, - ['all-items']=true, - ['repair']=true, - ['global-chat']=true, - ['set-home']=true, - ['home']=true, - ['return']=true, -}) -groups['Admin']:edit('allow',false,{ - ['player-list']=true, - ['readme']=true, - ['rockets']=true, - ['science']=true, - ['tasklist']=true, - ['rank-changer']=true, - ['admin-commands']=true, - ['warn']=true, - ['temp-ban']=true, - ['clear-warings']=true, - ['clear-reports']=true, - ['clear-all']=true, - ['clear-inv']=true, - ['announcements']=true, - ['warp-list']=true, - ['polls']=true, - ['global-chat']=true, - ['set-home']=true, - ['home']=true, - ['return']=true, -}) -groups['Donator']:edit('allow',false,{ - ['player-list']=true, - ['readme']=true, - ['rockets']=true, - ['science']=true, - ['tasklist']=true, - ['report']=true, - ['warp-list']=true, - ['polls']=true, - ['global-chat']=true, - ['set-home']=true, - ['home']=true, - ['return']=true, -}) -groups['User']:edit('allow',false,{ - ['player-list']=true, - ['readme']=true, - ['rockets']=true, - ['science']=true, - ['tasklist']=true, - ['report']=true, - ['warp-list']=true, - ['polls']=true -}) -groups['Jail']:edit('allow',false,{ - -}) - - - -groups['Root']:add_rank{ - name='Owner', - short_hand='Owner', - tag='[Owner]', - time=nil, - colour={r=170,g=0,b=0}, - is_admin = true, - is_spectator=true, - base_afk_time=false -} -groups['Root']:add_rank{ - name='Community Manager', - short_hand='Com Mngr', - tag='[Com Mngr]', - colour={r=150,g=68,b=161}, - is_admin = true, - is_spectator=true, - base_afk_time=false -} -groups['Root']:add_rank{ - name='Developer', - short_hand='Dev', - tag='[Dev]', - colour={r=179,g=125,b=46}, - is_admin = true, - is_spectator=true, - base_afk_time=false -} - -groups['Admin']:add_rank{ - name='Mod', - short_hand='Mod', - tag='[Mod]', - colour={r=0,g=170,b=0}, - disallow={ - 'server_command' - }, - is_admin = true, - is_spectator=true, - base_afk_time=false -} -groups['Admin']:add_rank{ - name='Trainee', - short_hand='TrMod', - tag='[Trainee]', - colour={r=0,g=196,b=137}, - disallow={ - 'server_command' - }, - is_spectator=true, - base_afk_time=false -} - -groups['Donator']:add_rank{ - name='Sponsor', - short_hand='Spon', - tag='[Sponsor]', - colour={r=247,g=246,b=54}, - power=8, - is_spectator=true, - base_afk_time=false -} -groups['Donator']:add_rank{ - name='Pay to Win', - short_hand='P2W', - tag='[P2W]', - colour={r=238,g=172,b=44}, - is_spectator=true, - base_afk_time=160 -} -groups['Donator']:add_rank{ - name='Donator', - short_hand='Don', - tag='[Donator]', - colour={r=230,g=99,b=34}, - is_spectator=true, - base_afk_time=120 -} - -groups['User']:add_rank{ - name='Partner', - short_hand='Part', - tag='[Partner]', - power=0, - colour={r=140,g=120,b=200}, - base_afk_time=120 -} -groups['User']:add_rank{ - name='Veteran', - short_hand='Vet', - tag='[Veteran]', - time=600, - power=1, - colour={r=26,g=118,b=156}, - base_afk_time=60 -} -groups['User']:add_rank{ - name='Regular', - short_hand='Reg', - tag='[Regular]', - time=180, - colour={r=79,g=155,b=163}, - power=3, - base_afk_time=30 -} - -local ranks = Ranking._ranks(true) - -ranks['Developer']:edit('allow',false,{ - ['cheat-mode']=true -}) - -ranks['Admin']:edit('allow',false,{ - ['game-settings']=true, - ['always-warp']=true, - ['admin-items']=true -}) -ranks['Mod']:edit('allow',false,{ - ['go-to']=true, - ['bring']=true, - ['no-report']=true -}) -ranks['Trainee']:edit('allow',false,{ - ['go-to']=true, - ['bring']=true, - ['no-report']=true -}) - -ranks['Sponsor']:edit('allow',false,{ - ['jail']=true, - ['unjail']=true, - ['bonus']=true, - ['bonus-respawn']=true -}) -ranks['Pay to Win']:edit('allow',false,{ - ['jail']=true, - ['unjail']=true, - ['bonus']=true, - ['bonus-respawn']=true -}) -ranks['Donator']:edit('allow',false,{ - -}) - -ranks['Partner']:edit('allow',false,{ - ['global-chat']=true -}) -ranks['Veteran']:edit('allow',false,{ - ['tree-decon']=true, - ['create-poll']=true, - ['repair']=true -}) -ranks['Member']:edit('allow',false,{ - ['edit-tasklist']=true, - ['make-warp']=true, - ['nuke']=true, - ['base-damage']=true, - ['varified']=true -}) -ranks['Regular']:edit('allow',false,{ - ['kill']=true, - ['decon']=true, - ['capsules']=true -}) -ranks['Guest']:edit('allow',false,{ - ['tag']=true, - ['tag-clear']=true, - ['report']=true -}) - -Ranking._base_preset{ - ['badgamernl']='Owner', - ['arty714']='Community Manager', - ['cooldude2606']='Developer', - ['mark9064']='Admin', - ['Drahc_pro']='Admin', - ['propangaseddy']='Admin', - ['aldldl']='Admin' -} diff --git a/Boiler Print Module b/Boiler Print Module new file mode 100644 index 00000000..b53932ae --- /dev/null +++ b/Boiler Print Module @@ -0,0 +1,37 @@ +--- Desction +-- @module ThisModule@X.Y.Z +-- @author +-- @license +-- @alias ThisModule + +-- Module Require +local Module = require('Module') +local SubModule = require('Collection.Submodule') +local OptModule -- OptModule@^X.Y.Z + +-- Local Variables + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function(self) + if loaded_modules['OptModule'] then OptModule = require('OptModule') end + if loaded_modules['OptModule2'] then require(module_path..'/src/module2',{self=self}) end + --code + end, + on_post=function() + --code + end +} + +-- Global Define +local global = global{ + key='value' +} + +-- Function Define + +-- Event Handlers Define + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/ExpCore/GuiParts/center.lua b/ExpCore/GuiParts/center.lua deleted file mode 100644 index 0cf0f107..00000000 --- a/ExpCore/GuiParts/center.lua +++ /dev/null @@ -1,209 +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 center = {} -center._center = {} - ---- Adds a new obj to the center gui --- @usage Gui.center.add{name='foo',caption='Foo',tooltip='Testing',draw=function} --- @param obj contains the new object, needs name, fraw is opt and is function(root_frame) --- @return the object made, used to add tabs -function center.add(obj) - if not is_type(obj,'table') then return end - if not is_type(obj.name,'string') then return end - verbose('Created Center Gui: '..obj.name) - setmetatable(obj,{__index=center._center}) - obj.tabs = {} - obj._tabs = {} - Gui._add_data('center',obj.name,obj) - Gui.toolbar.add(obj.name,obj.caption,obj.tooltip,obj.open) - return obj -end - ---- Used to get the center frame of the player, used mainly in script --- @usage Gui.center.get_flow(player) -- returns gui emelemt --- @param player a player indifier to get the flow for --- @treturn table the gui element flow -function center.get_flow(player) - local player = Game.get_player(player) - return player.gui.center.exp_center or player.gui.center.add{name='exp_center',type='flow'} -end - ---- Used to open a center frame for a player --- @usage Gui.center.open(player,'server-info') -- return true --- @param player a player indifier to get the flow for --- @tparam center string the name of the center frame to open --- @treturn boelon based on if it successed or not -function center.open(player,center) - local player = Game.get_player(player) - Gui.center.clear(player) - if not Gui._get_data('center')[center] then return false end - Gui._get_data('center')[center].open{ - element={name=center}, - player_index=player.index - } - return true -end - ---- Used to open a center frame for a player --- @usage Gui.center.open_tab(player,'readme','rules') -- return true --- @param player a player indifier to get the flow for --- @tparam center string the name of the center frame to open --- @tparam tab string the name of the tab to open --- @treturn boelon based on if it successed or not -function center.open_tab(player,center,tab) - local player = Game.get_player(player) - if not Gui.center.open(player,center) then return false end - local name = center..'_'..tab - if not Gui._get_data('inputs_button')[name] then return false end - Gui._get_data('inputs_button')[name].events[defines.events.on_gui_click]{ - element=Gui.center.get_flow(player)[center].tab_bar.tab_bar_scroll.tab_bar_scroll_flow[name], - } - return true -end - ---- Used to clear the center frame of the player, used mainly in script --- @usage Gui.center.clear(player) --- @param player a player indifier to get the flow for -function center.clear(player) - local player = Game.get_player(player) - center.get_flow(player).clear() -end - --- used on the button press when the toolbar button is press, can be overriden --- not recomented for direct use see Gui.center.open -function center._center.open(event) - local player = Game.get_player(event) - local _center = Gui._get_data('center')[event.element.name] - local center_flow = center.get_flow(player) - if center_flow[_center.name] then Gui.center.clear(player) return end - local center_frame = center_flow.add{ - name=_center.name, - type='frame', - caption=_center.caption, - direction='vertical', - style=mod_gui.frame_style - } - if is_type(center_frame.caption,'string') and player.gui.is_valid_sprite_path(center_frame.caption) then center_frame.caption = '' end - if is_type(_center.draw,'function') then - local success, err = pcall(_center.draw,_center,center_frame) - if not success then error(err) end - else error('No Callback on center frame '.._center.name) - end - player.opened=center_frame -end - --- this is the default draw function if one is not provided, can be overriden --- not recomented for direct use see Gui.center.open -function center._center:draw(frame) - Gui.bar(frame,510) - local tab_bar = frame.add{ - type='frame', - name='tab_bar', - style='image_frame', - direction='vertical' - } - tab_bar.style.width = 510 - tab_bar.style.height = 65 - local tab_bar_scroll = tab_bar.add{ - type='scroll-pane', - name='tab_bar_scroll', - horizontal_scroll_policy='auto-and-reserve-space', - vertical_scroll_policy='never' - } - tab_bar_scroll.style.vertically_squashable = false - tab_bar_scroll.style.vertically_stretchable = true - tab_bar_scroll.style.width = 500 - local tab_bar_scroll_flow = tab_bar_scroll.add{ - type='flow', - name='tab_bar_scroll_flow', - direction='horizontal' - } - Gui.bar(frame,510) - local tab = frame.add{ - type ='frame', - name='tab', - direction='vertical', - style='image_frame' - } - tab.style.width = 510 - tab.style.height = 305 - local tab_scroll = tab.add{ - type ='scroll-pane', - name='tab_scroll', - horizontal_scroll_policy='never', - vertical_scroll_policy='auto' - } - tab_scroll.style.vertically_squashable = false - tab_scroll.style.vertically_stretchable = true - tab_scroll.style.width = 500 - local tab_scroll_flow = tab_scroll.add{ - type='flow', - name='tab_scroll_flow', - direction='vertical' - } - tab_scroll_flow.style.width = 480 - Gui.bar(frame,510) - local first_tab = nil - for name,button in pairs(self.tabs) do - first_tab = first_tab or name - button:draw(tab_bar_scroll_flow).style.font_color = defines.color.white - end - self._tabs[self.name..'_'..first_tab](tab_scroll_flow) - tab_bar_scroll_flow.children[1].style.font_color = defines.color.orange - frame.parent.add{type='frame',name='temp'}.destroy()--recenter the GUI -end - ---- If deafult draw is used then you can add tabs to the gui with this function --- @usage _center:add_tab('foo','Foo','Just a tab',function) --- @tparam string name this is the name of the tab --- @tparam string caption this is the words that appear on the tab button --- @tparam[opt] string tooltip the tooltip that is on the button --- @tparam function callback this is called when button is pressed with function(root_frame) --- @return self to allow chaining of _center:add_tab -function center._center:add_tab(name,caption,tooltip,callback) - verbose('Created Tab: '..self.name..'/'..name) - self._tabs[self.name..'_'..name] = callback - self.tabs[name] = Gui.inputs.add{ - type='button', - name=self.name..'_'..name, - caption=caption, - tooltip=tooltip - }:on_event('click',function(event) - local tab = event.element.parent.parent.parent.parent.tab.tab_scroll.tab_scroll_flow - tab.clear() - local frame_name = tab.parent.parent.parent.name - local _center = Gui._get_data('center')[frame_name] - local _tab = _center._tabs[event.element.name] - if is_type(_tab,'function') then - for _,button in pairs(event.element.parent.children) do - if button.name == event.element.name then - button.style.font_color = defines.color.orange - else - button.style.font_color = defines.color.white - end - end - local success, err = pcall(_tab,tab) - if not success then error(err) end - end - end) - return self -end - --- used so that when gui close key is pressed this will close the gui -Event.register(defines.events.on_gui_closed,function(event) - if event.element and event.element.valid then event.element.destroy() end -end) - --- when the player rank is changed it closses the center guis -if defines.events.rank_change then - Event.register(defines.events.rank_change,center.clear) -end - -return center \ No newline at end of file diff --git a/ExpCore/GuiParts/left.lua b/ExpCore/GuiParts/left.lua deleted file mode 100644 index 372f0289..00000000 --- a/ExpCore/GuiParts/left.lua +++ /dev/null @@ -1,177 +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 left = {} -left._left = {} - --- used for debugging -function left.override_open(state) - Gui._global().over_ride_left_can_open = state -end ---- Used to add a left gui frame --- @usage Gui.left.add{name='foo',caption='Foo',tooltip='just testing',open_on_join=true,can_open=function,draw=function} --- @param obj this is what will be made, needs a name and a draw function(root_frame), open_on_join can be used to set the deaful state true/false, can_open is a test to block it from opening but is not needed --- @return the object that is made to... well idk but for the future -function left.add(obj) - if not is_type(obj,'table') then return end - if not is_type(obj.name,'string') then return end - verbose('Created Left Gui: '..obj.name) - setmetatable(obj,{__index=left._left}) - Gui._add_data('left',obj.name,obj) - Gui.toolbar.add(obj.name,obj.caption,obj.tooltip,obj.toggle) - return obj -end - ---- This is used to update all the guis of conected players, good idea to use our thread system as it as nested for loops --- @usage Gui.left.update() --- @tparam[opt] string frame this is the name of a frame if you only want to update one --- @param[opt] players the player to update for, if not given all players are updated, can be one player -function left.update(frame,players) - if not Server or not Server._thread then - local players = is_type(players,'table') and #players > 0 and {unpack(players)} or is_type(players,'table') and {players} or Game.get_player(players) and {Game.get_player(players)} or game.connected_players - for _,player in pairs(players) do - local frames = Gui._get_data('left') or {} - if frame then frames = {[frame]=frames[frame]} or {} end - for name,left in pairs(frames) do - if _left then - local fake_event = {player_index=player.index,element={name=name}} - left.open(fake_event) - end - end - end - else - local frames = Gui._get_data('left') or {} - if frame then frames = {[frame]=frames[frame]} or {} end - local players = is_type(players,'table') and #players > 0 and {unpack(players)} or is_type(players,'table') and {players} or Game.get_player(players) and {Game.get_player(players)} or game.connected_players - Server.new_thread{ - data={players=players,frames=frames} - }:on_event('tick',function(thread) - if #thread.data.players == 0 then thread:close() return end - local player = table.remove(thread.data.players,1) - Server.new_thread{ - data={player=player,frames=thread.data.frames} - }:on_event('resolve',function(thread) - for name,left in pairs(thread.data.frames) do - if left then - local fake_event = {player_index=thread.data.player.index,element={name=name}} - left.open(fake_event) - end - end - end):queue() - end):open() - end -end - ---- Used to open the left gui of every player --- @usage Gui.left.open('foo') --- @tparam string left_name this is the gui that you want to open -function left.open(left_name) - local _left = Gui._get_data('left')[left_name] - if not _left then return end - if not Server or not Server._thread then - for _,player in pairs(game.connected_players) do - local left_flow = mod_gui.get_frame_flow(player) - if left_flow[_left.name] then left_flow[_left.name].style.visible = true end - end - else - Server.new_thread{ - data={players=game.connected_players} - }:on_event('tick',function(thread) - if #thread.data.players == 0 then thread:close() return end - local player = table.remove(thread.data.players,1) - local left_flow = mod_gui.get_frame_flow(player) - if left_flow[_left.name] then left_flow[_left.name].style.visible = true end - end):open() - end -end - ---- Used to close the left gui of every player --- @usage Gui.left.close('foo') --- @tparam string left_name this is the gui that you want to close -function left.close(left_name) - local _left = Gui._get_data('left')[left_name] - if not _left then return end - if not Server or not Server._thread then - for _,player in pairs(game.connected_players) do - local left_flow = mod_gui.get_frame_flow(player) - if left_flow[_left.name] then left_flow[_left.name].style.visible = false end - end - else - Server.new_thread{ - data={players=game.connected_players} - }:on_event('tick',function(thread) - if #thread.data.players == 0 then thread:close() return end - local player = table.remove(thread.data.players,1) - local left_flow = mod_gui.get_frame_flow(player) - if left_flow[_left.name] then left_flow[_left.name].style.visible = false end - end):open() - end -end - --- this is used to draw the gui for the first time (these guis are never destoryed), used by the script -function left._left.open(event) - local player = Game.get_player(event) - local _left = Gui._get_data('left')[event.element.name] - local left_flow = mod_gui.get_frame_flow(player) - local frame = nil - if left_flow[_left.name] then - frame = left_flow[_left.name] - frame.clear() - else - frame = left_flow.add{type='frame',name=_left.name,style=mod_gui.frame_style,caption=_left.caption,direction='vertical'} - frame.style.visible = false - if is_type(_left.open_on_join,'boolean') then frame.style.visible = _left.open_on_join end - end - if is_type(_left.draw,'function') then _left.draw(frame) else frame.style.visible = false error('No Callback On '.._left.name) end -end - --- this is called when the toolbar button is pressed -function left._left.toggle(event) - local player = Game.get_player(event) - local _left = Gui._get_data('left')[event.element.name] - local left_flow = mod_gui.get_frame_flow(player) - if not left_flow[_left.name] then _left.open(event) end - local left = left_flow[_left.name] - local open = false - if is_type(_left.can_open,'function') then - local success, err = pcall(_left.can_open,player) - if not success then error(err) - elseif err == true then open = true - elseif Gui._global().over_ride_left_can_open then - if is_type(Ranking,'table') and Ranking._presets and Ranking._presets().meta.rank_count > 0 then - if Ranking.get_rank(player):allowed(_left.name) then open = true - else open = {gui.unauthorized} end - end - else open = err end - else - if is_type(Ranking,'table') and Ranking._presets and Ranking._presets().meta.rank_count > 0 then - if Ranking.get_rank(player):allowed(_left.name) then open = true - else open = {gui.unauthorized} end - end - end - if open == true and left.style.visible ~= true then - left.style.visible = true - else - left.style.visible = false - end - if open == false then player_return({'gui.cant-open-no-reason'},defines.text_color.crit,player) player.play_sound{path='utility/cannot_build'} - elseif open ~= true then player_return({'gui.cant-open',open},defines.text_color.crit,player) player.play_sound{path='utility/cannot_build'} end -end - --- draws the left guis when a player first joins, fake_event is just because i am lazy -Event.register(defines.events.on_player_joined_game,function(event) - local player = Game.get_player(event) - local frames = Gui._get_data('left') or {} - for name,left in pairs(frames) do - local fake_event = {player_index=player.index,element={name=name}} - left.open(fake_event) - end -end) - -return left \ No newline at end of file diff --git a/ExpCore/GuiParts/popup.lua b/ExpCore/GuiParts/popup.lua deleted file mode 100644 index c0708093..00000000 --- a/ExpCore/GuiParts/popup.lua +++ /dev/null @@ -1,112 +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 popup = {} -popup._popup = {} - -function popup._load() - popup._popup.close = Gui.inputs.add{ - type='button', - name='popup-close', - caption='utility/set_bar_slot', - tooltip='Close This Popup' - }:on_event('click',function(event) - local frame = event.element.parent - if frame and frame.valid then frame.destroy() end - end) -end - ---- Used to add a popup gui style --- @usage Gui.left.add{name='foo',caption='Foo',draw=function} --- @param obj this is what will be made, needs a name and a draw function(root_frame,data) --- @return the object that is made to... well idk but for the future -function popup.add(obj) - if not is_type(obj,'table') then return end - if not is_type(obj.name,'string') then return end - verbose('Created Popup Gui: '..obj.name) - setmetatable(obj,{__index=popup._popup}) - local name = obj.name; obj.name = nil - Gui._add_data('popup',name,obj) - obj.name = name - return obj -end - --- this is used by the script to find the popup flow -function popup.flow(player) - local player = Game.get_player(player) - local flow = mod_gui.get_frame_flow(player).popups or mod_gui.get_frame_flow(player).add{name='popups',type='flow',direction='vertical'} - return flow -end - ---- Use to open a popup for these players --- @usage Gui.popup.open('ban',nil,{player=1,reason='foo'}) --- @tparam string style this is the name you gave to the popup when added --- @param data this is the data that is sent to the draw function --- @tparam[opt=game.connected_players] table players the players to open the popup for -function popup.open(style,data,players) - local _popup = Gui._get_data('popup')[style] - local players = players or game.connected_players - local data = data or {} - if not _popup then return end - if _popup.left then Gui.left.close(_popup.left.name) end - if not Server or not Server._thread then - for _,player in pairs(players) do - local flow = popup.flow(player) - local _frame = flow.add{ - type='frame', - direction='horizontal', - style=mod_gui.frame_style - } - local frame = _frame.add{ - type='frame', - name='inner_frame', - direction='vertical', - style='image_frame' - } - _popup.close:draw(_frame) - if is_type(_popup.draw,'function') then - local success, err = pcall(_popup.draw,frame,data) - if not success then error(err) end - else error('No Draw On Popup '.._popup.name) end - end - else - Server.new_thread{ - data={players=players,popup=_popup,data=data} - }:on_event('tick',function(thread) - if #thread.data.players == 0 then thread:close() return end - local player = table.remove(thread.data.players,1) - local flow = popup.flow(player) - local _frame = flow.add{ - type='frame', - direction='horizontal', - style=mod_gui.frame_style - } - local frame = _frame.add{ - type='frame', - name='inner_frame', - direction='vertical', - style='image_frame' - } - thread.data.popup.close:draw(_frame) - if is_type(thread.data.popup.draw,'function') then - local success, err = pcall(thread.data.popup.draw,frame,thread.data.data) - if not success then error(err) end - else error('No Draw On Popup '..thread.data.popup.name) end - end):open() - end -end - -function popup._popup:add_left(obj) - obj.name = obj.name or self.name - self.left = Gui.left.add(obj) -end - -Event.register(defines.events.on_player_joined_game,popup.flow) - -return popup \ No newline at end of file diff --git a/ExpCore/GuiParts/toolbar.lua b/ExpCore/GuiParts/toolbar.lua deleted file mode 100644 index f197312e..00000000 --- a/ExpCore/GuiParts/toolbar.lua +++ /dev/null @@ -1,51 +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) - verbose('Created Toolbar Button: '..name) - 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() - if not Gui._get_data('toolbar') then return end - 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 -Event.register(defines.events.on_player_joined_game,toolbar.draw) - -return toolbar \ No newline at end of file diff --git a/ExpCore/commands.lua b/ExpCore/commands.lua deleted file mode 100644 index 8b6ca10e..00000000 --- a/ExpCore/commands.lua +++ /dev/null @@ -1,151 +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 " " --- @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 commands.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 rank:allowed(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', - game.tick - ..' Player: "'..player_name..'"' - ..' Failed to use command (Unauthorized): "'..command.name..'"' - ..' With args of: '..table.to_string(command_args(command,command_data)) - ..'\n' - , 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', - game.tick - ..' Player: "'..player_name..'"' - ..' Failed to use command (Invalid Args): "'..command.name..'"' - ..' With args of: '..table.to_string(args) - ..'\n' - , true, 0) - return - end - -- runs the command - local success, err = pcall(command_calls[command.name],command,args) - if not success then error(err) end - if err ~= commands.error and player_name ~= 'server' then player_return({'commands.command-ran'},defines.text_color.info) end - game.write_file('commands.log', - game.tick - ..' Player: "'..player_name..'"' - ..' Used command: "'..command.name..'"' - ..' With args of: '..table.to_string(args) - ..'\n' - , true, 0) -end - --- this is a set of constants you can use -commands._add_command = commands.add_command --if you dont want to use the custom commands interface -commands._expgaming = true --if you want to test if the custom commands are present -commands.error = 'COMMAND_ERROR' --if returned during a custom command, Command Complete message not printed ---- 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 - verbose('Created Command: '..name) - 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,function(...) - local success, err = pcall(run_custom_command,...) - if not success then error(err) end - end) -end \ No newline at end of file diff --git a/ExpCore/gui.lua b/ExpCore/gui.lua deleted file mode 100644 index 5f33bcba..00000000 --- a/ExpCore/gui.lua +++ /dev/null @@ -1,200 +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 = {} - --- only really used when parts of expcore are missing, or script debuging (ie to store the location of frames) -function Gui._global(reset) - global.exp_core = not reset and global.exp_core or {} - global.exp_core.gui = not reset and global.exp_core.gui or {} - return global.exp_core.gui -end - --- 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 - verbose('Gui Extraction: '..part) - self[part] = require('GuiParts/'..part) - end -end - ---- Add a white bar to any gui frame --- @usage Gui.bar(frame,100) --- @param frame the frame to draw the line to --- @param[opt=10] width the width of the bar --- @return the line that was made type is progressbar -function Gui.bar(frame,width) - local line = frame.add{ - type='progressbar', - size=1, - value=1 - } - line.style.height = 3 - line.style.width = width or 10 - line.style.color = defines.color.white - return line -end - ---- Used to set the index of a drop down to a certian item --- @usage Gui.set_dropdown_index(dropdown,player.name) --- @param dropdown the dropdown that is to be effected --- @param _item this is the item to look for --- @return returns the dropdown if it was successful -function Gui.set_dropdown_index(dropdown,_item) - if dropdown and dropdown.valid and dropdown.items and _item then else return end - local _index = 1 - for index, item in pairs(dropdown.items) do - if item == _item then _index = index break end - end - dropdown.selected_index = _index - return dropdown -end - -Event.register(-1,function(event) - if Server and Server._thread then - Server.new_thread{ - name='camera-follow', - data={cams={},cam_index=1,players={}} - }:on_event('tick',function(self) - local update = 4 - if self.data.cam_index >= #self.data.cams then self.data.cam_index = 1 end - if update > #self.data.cams then update = #self.data.cams end - for cam_offset = 0,update do - local _cam = self.data.cams[self.data.cam_index+cam_offset] - if not _cam then break end - if not _cam.cam.valid then table.remove(self.data.cams,self.data.cam_index) - elseif not _cam.entity.valid then table.remove(self.data.cams,self.data.cam_index) - else _cam.cam.position = _cam.entity.position if not _cam.surface then _cam.cam.surface_index = _cam.entity.surface.index end - end - end - self.data.cam_index = self.data.cam_index+update - end):on_event('error',function(self,err) - -- posible error handling if needed - error(err) - end):on_event(defines.events.on_player_respawned,function(self,event) - if self.data.players[event.player_index] then - local remove = {} - local player = Game.get_player(event) - for index,cam in pairs(self.data.players[event.player_index]) do - if cam.valid then table.insert(self.data.cams,{cam=cam,entity=player.character,surface=player.surface}) - else table.insert(remove,index) end - end - for n,index in pairs(remove) do - table.remove(self.data.players[event.player_index],index-n+1) - end - end - end):open() - end -end) - ---- Adds a camera that updates every tick (or less depeading on how many are opening) it will move to follow an entity --- @usage Gui.cam_link{entity=game.player.character,frame=frame,width=50,hight=50,zoom=1} --- @usage Gui.cam_link{entity=game.player.character,cam=frame.camera,surface=game.surfaces['testing']} --- @param entity this is the entity that the camera will follow --- @param[opt] cam a camera that you already have in the gui --- @param[opt] frame the frame to add the camera to, no effect if cam param is given --- @param[chain=frame] zoom the zoom to give the new camera --- @param[chain=frame] width the width to give the new camera --- @param[chain=frame] height the height to give the new camera --- @param[opt] surface this will over ride the surface that the camera follows on, allowing for a 'ghost surface' while keeping same position --- @param[opt] respawn_open if set to true then the camera will auto re link to the player after a respawn --- @return the camera that the function used be it made or given as a param -function Gui.cam_link(data) - if not data.entity or not data.entity.valid then return end - if is_type(data.cam,'table') and data.cam.__self and data.cam.valid then - data.cam = data.cam - elseif data.frame then - data.cam={} - data.cam.type='camera' - data.cam.name='camera' - data.cam.position= data.entity.position - data.cam.surface_index= data.surface and data.surface.index or data.entity.surface.index - data.cam.zomm = data.zoom - data.cam = data.frame.add(data.cam) - data.cam.style.width = data.width or 100 - data.cam.style.height = data.height or 100 - else return end - if not Server or not Server._thread or not Server.get_thread('camera-follow') then - if not Gui._global().cams then - Gui._global().cams = {} - Gui._global().cam_index = 1 - end - if data.cam then - local surface = data.surface and data.surface.index or nil - table.insert(Gui._global().cams,{cam=data.cam,entity=data.entity,surface=surface}) - end - if not Gui._global().players then - Gui._global().players = {} - end - if data.respawn_open then - if data.entity.player then - if not Gui._global().players[data.entity.player.index] then Gui._global().players[data.entity.player.index] = {} end - table.insert(Gui._global().players[data.entity.player.index],data.cam) - end - end - else - local thread = Server.get_thread('camera-follow') - local surface = data.surface and data.surface.index or nil - table.insert(thread.data.cams,{cam=data.cam,entity=data.entity,surface=surface}) - if data.respawn_open then - if data.entity.player then - if not thread.data.players[data.entity.player.index] then thread.data.players[data.entity.player.index] = {} end - table.insert(thread.data.players[data.entity.player.index],data.cam) - end - end - end - return data.cam -end - -Event.register(defines.events.on_tick, function(event) - if Gui.left and ((event.tick+10)/(3600*game.speed)) % 15 == 0 then - Gui.left.update() - end - if Server and Server._thread then return end - if Gui._global().cams and is_type(Gui._global().cams,'table') and #Gui._global().cams > 0 then - local update = 4 - if Gui._global().cam_index >= #Gui._global().cams then Gui._global().cam_index = 1 end - if update > #Gui._global().cams then update = #Gui._global().cams end - for cam_offset = 0,update do - local _cam = Gui._global().cams[Gui._global().cam_index] - if not _cam then break end - if not _cam.cam.valid then table.remove(Gui._global().cams,Gui._global().cam_index) - elseif not _cam.entity.valid then table.remove(Gui._global().cams,Gui._global().cam_index) - else _cam.cam.position = _cam.entity.position if not _cam.surface then _cam.cam.surface_index = _cam.entity.surface.index end Gui._global().cam_index = Gui._global().cam_index+1 - end - end - Gui._global().cam_index = Gui._global().cam_index+update - end -end) - -Event.register(defines.events.on_player_respawned,function(event) - if Server and Server._thread then return end - if Gui._global().players and is_type(Gui._global().players,'table') and #Gui._global().players > 0 and Gui._global().players[event.player_index] then - local remove = {} - local player = Game.get_player(event) - for index,cam in pairs(Gui._global().players[event.player_index]) do - if cam.valid then table.insert(Gui._global().cams,{cam=cam,entity=player.character,surface=player.surface}) - else table.insert(remove,index) end - end - for n,index in pairs(remove) do - table.remove(Gui._global().players[event.player_index],index-n+1) - end - end -end) - -return Gui \ No newline at end of file diff --git a/ExpCore/load.lua b/ExpCore/load.lua deleted file mode 100644 index 2365a0c5..00000000 --- a/ExpCore/load.lua +++ /dev/null @@ -1,43 +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.Ranking = require('ranking') -StdExpCoreLib.Server = require('server') -StdExpCoreLib.Sync = require('sync') -StdExpCoreLib.Gui = require('gui') -verbose('Begain Gui Part Loading') -StdExpCoreLib.Gui:_load_parts{ - 'inputs', - 'toolbar', - 'center', - 'left', - 'popup' -} - -return function(rtn) - local _return = {} - for _,name in pairs(rtn) do - if StdExpCoreLib[name] then - verbose('Core File Extraction: '..name) - table.insert(_return,StdExpCoreLib[name]) - end - end - return unpack(_return) -end \ No newline at end of file diff --git a/ExpCore/ranking.lua b/ExpCore/ranking.lua deleted file mode 100644 index bad35ad0..00000000 --- a/ExpCore/ranking.lua +++ /dev/null @@ -1,384 +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 is just for debuging when setting you rank powers -function Ranking.output_ranks(player) - local player = Game.get_player(player) or game.player or nil - if not player then return end - for power,rank in pairs(Ranking._ranks()) do - local output = power..') '..rank.name - output=output..' '..rank.tag - local admin = 'No'; if rank.is_root then admin = 'Root' elseif rank.is_admin then admin = 'Yes' end - output=output..' Admin: '..admin - output=output..' Group: '..rank.group.name - output=output..' AFK: '..tostring(rank.base_afk_time) - player_return(output,rank.colour,player) - end -end - --- 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={},last_jail=nil} 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 nil - else - _return = mixed.group and mixed or nil - 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 nil - 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,true) 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 is_type(by_player,'string') and by_player 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 - if player.online_time > 60 or by_player_name ~= 'server' then game.print({message,player.name,rank.name,by_player_name},print_colour) end - 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 old_rank.group.name ~= 'Jail' then Ranking._presets().old[player.index] = old_rank.name end - player.admin = rank.is_admin or false - player.spectator = rank.is_spectator or false - 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 - if rank.group.name == 'Jail' and Ranking._presets().last_jail ~= player.name then - Sync.emit_embeded{ - title='Player Jail', - color=Color.to_hex(defines.text_color.med), - description='There was a player jailed.', - ['Player:']=player.name, - ['By:']='<>'..by_player_name, - ['Reason:']='No Reason' - } - end - game.write_file('ranking-change.json', - table.json({ - tick=tick, - play_time=player.online_time, - player_name=player.name, - by_player_name=by_player_name, - new_rank=rank.name, - old_rank=old_rank.name, - power_increase=(old_rank.power-rank.power) - })..'\n' - , true, 0) -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)]) - 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 = current_rank - for _,rank in pairs(ranks) do - if rank.power < _rank.power or _rank.power == -1 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(self.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,show_default) - local colour = colour or defines.color.white - local meta_data = Ranking._presets().meta - local default = Ranking.get_rank(meta_data.default) - if not Server or not Server._thread then - for _,player in pairs(self:get_players(true)) do - if self.name == default.name or show_default then - player_return({'ranking.all-rank-print',rtn},colour,player) - else - player_return({'ranking.rank-print',self.name,rtn},colour,player) - end - end - else - -- using threads to make less lag - Server.new_thread{ - data={rank=self,rtn=rtn,default=default.name,all=show_default} - }: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 - if thread.data.rank.name == thread.data.default or thread.data.all then - player_return({'ranking.all-rank-print',thread.data.rtn},colour,player) - else - player_return({'ranking.rank-print',thread.data.rank.name,thread.data.rtn},colour,player) - end - 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 - verbose('Edited Rank: '..self.name..'/'..key) - 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 - verbose('Created Group: '..obj.name) - 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={}} --- if the rank is given power then it is given that place realative to the highest rank in that group,if no power then it is added to the end -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 - verbose('Created Rank: '..obj.name) - setmetatable(obj,{__index=Ranking._rank}) - obj.group = self - obj.allow = obj.allow or {} - obj.disallow = obj.disallow or {} - obj.power = obj.power and self.highest and self.highest.power+obj.power or obj.power or self.lowest and self.lowest.power+1 or nil - 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 - verbose('Edited Group: '..self.name..'/'..key) - 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) - -Event.register(defines.events.on_tick,function(event) - if (((event.tick+10)/(3600*game.speed))+(15/2))% 15 == 0 then - -- this is the system to auto rank players - if not Server or not Server._thread then - for _,player in pairs(game.connected_players) do - Ranking.find_preset(player,tick) - end - else - Server.new_thread{ - data={players=game.connected_players} - }:on_event('tick',function(thread) - if #thread.data.players == 0 then thread:close() return end - local player = table.remove(thread.data.players,1) - Ranking.find_preset(player,tick) - end):open() - end - end -end) - -return Ranking \ No newline at end of file diff --git a/ExpCore/ranks.lua b/ExpCore/ranks.lua deleted file mode 100644 index 1b4495d2..00000000 --- a/ExpCore/ranks.lua +++ /dev/null @@ -1,230 +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', - 'open_character_gui', - 'begin_mining', - 'start_walking', - 'player_leave_game', - 'open_blueprint_library_gui', - 'build_item', - 'use_item', - 'select_item', - 'rotate_entity', - 'open_train_gui', - 'open_train_station_gui', - 'open_gui', - 'open_item', - 'deconstruct', - 'build_rail', - 'cancel_research', - 'start_research', - 'set_train_stopped', - 'select_gun', - 'open_technology_gui', - 'open_trains_gui', - 'edit_custom_tag', - 'craft', - 'setup_assembling_machine', - } -} - --- 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, - is_admin=true, - is_spectator=true, - base_afk_time=false -} - -admin:add_rank{ - name='Admin', - short_hand='Admin', - tag='[Admin]', - colour={r=233,g=63,b=233}, - is_admin=true, - is_spectator=true, - base_afk_time=false -} - -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' - }, - base_afk_time=60 -} -user:add_rank{ - name='Guest', - short_hand='', - tag='', - colour={r=185,g=187,b=160}, - is_default=true, - disallow={ - 'build_terrain', - 'remove_cables', - 'launch_rocket', - 'reset_assembling_machine', - 'cancel_research' - }, - base_afk_time=10 -} - -jail:add_rank{ - name='Jail', - short_hand='Jail', - tag='[Jail]', - colour={r=50,g=50,b=50}, - disallow={}, - base_afk_time=false -} - -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 - local rank = ranks[power] - rank:edit('disallow',false,rank.group.disallow) - 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 = rank.time end - end - end - return meta -end \ No newline at end of file diff --git a/ExpCore/server.lua b/ExpCore/server.lua deleted file mode 100644 index ed79419c..00000000 --- a/ExpCore/server.lua +++ /dev/null @@ -1,427 +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, position, entity, tile = game.player, game.player.surface, game.player.force, game.player.position, game.player.selected, game.player.surface.get_tile(game.player.position);'..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) - if not success and is_type(err,'string') then local _end = string.find(err,'stack traceback') if _end then err = string.sub(err,0,_end-2) end end - if err or err == false then player_return(err) end - 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 threads.paused[self.name] then threads.paused[self.name] = nil end - 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 - self.opened=nil - if self.reopen == true then self:open() else - if is_type(self.name,'string') then threads.paused[self.name]=self.uuid - else threads.all[uuid] = nil threads.all._n = threads.all._n-1 end - 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) - if event.tick < 10 then return end - 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 -]] \ No newline at end of file diff --git a/ExpCore/sync.lua b/ExpCore/sync.lua deleted file mode 100644 index 03eb48be..00000000 --- a/ExpCore/sync.lua +++ /dev/null @@ -1,361 +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----------------------------------------------------------- --- this file is used to allow easy syncing with out side programes -local Sync = {} -local Sync_gui_functions = {} -local Sync_updates = {} - ---- Used as a faster way to get to the ranking function, overrides previous --- @usage Sync.set_ranks{name=rank_name} -function Sync.set_ranks(...) - Ranking._base_preset(...) -end - ---- Used to standidise the tick format for any sync info --- @usage Sync.tick_format(60) -- return {60,'1.00M'} -function Sync.tick_format(tick) - return {tick,tick_to_display_format(tick)} -end - ---- Prints to chat as if it were a player --- @usage Sync.print('Test','Cooldude2606') --- @param player_message the message to be printed in chat --- @param player_name the name of the player sending the message --- @param[opt] player_tag the tag apllied to the player's name --- @param[opt] plyaer_colour the colour of the message --- @param[opt] prefix add a prefix before the chat eg [IRC] -function Sync.print(player_message,player_name,player_tag,player_colour,prefix) - if not player_message then return 'No Message Found' end - local player = game.player or game.players[player_name] - local tag = player_tag and player_tag ~= '' and ' '..player_tag or '' - local colour = player_colour and player_colour ~= '' and player_colour or '#FFFFFF' - local prefix = prefix and prefix..' ' or '' - if player then - tag = ' '..player.tag - colour = player.chat_color - player_name = player.name - else - if colour:find('#') then - colour = Color.from_hex(colour) - else - colour = defines.color[player_colour] - end - end - game.print(prefix..player_name..tag..': '..player_message,colour) -end - ---- Logs an embed to the json.data we use a js script to add things we cant here --- @usage Sync.emit_embeded{title='BAN',color='0x0',description='A player was banned' ... } --- @tparam table arg a table which contains everything that the embeded will use --- @param[opt=''] title the tile of the embed --- @param[opt='0x0'] color the color given in hex you can use Color.to_hex{r=0,g=0,b=0} --- @param[opt=''] description the description of the embed --- @param[opt=''] server_detail sting to add onto the pre-set server detail --- @param[opt] fieldone the filed to add to the embed (key is name) (value is text) (start value with <> to make inline) --- @param[optchain] fieldtwo -function Sync.emit_embeded(args) - if not is_type(args,'table') then return end - local title = is_type(args.title,'string') and args.title or '' - local color = is_type(args.color,'string') and args.color:find("0x") and args.color or '0x0' - local description = is_type(args.description,'string') and args.description or '' - local server_detail = is_type(args.server_detail,'string') and args.server_detail or '' - local mods_online = 'Mods Online: '..Sync.info().players.admins_online - local done, fields = {title=true,color=true,description=true,server_detail=true}, {{ - name='Server Details', - value='Server Name: {{ serverName }} Online Players: '..#game.connected_players..' '..mods_online..' Server Time: '..tick_to_display_format(game.tick)..' '..server_detail - }} - for key, value in pairs(args) do - if not done[key] then - done[key] = true - local f = {name=key,value='',inline=false} - local value, inline = value:gsub("<>",'',1) - f.value = value - if inline > 0 then f.inline = true end - table.insert(fields,f) - end - end - local log_data = { - title=title, - description=description, - color=color, - fields=fields - } - game.write_file('embeded.json',table.json(log_data)..'\n',true,0) -end - --- set up error handle -verbose('Set New Error Handle') -_G.error_handle = function(err) - local color = _G.Color and Color.to_hex(defines.text_color.bg) or '0x0' - Sync.emit_embeded{title='SCRIPT ERROR',color=color,description='There was an error in the script @Developers ',Error=err} -end - ---- used to get the number of admins currently online --- @usage Sync.count_admins() --- @treturn int the number of admins online -function Sync.count_admins() - if not game then return 0 end - local _count = 0 - for _,player in pairs(game.connected_players) do - if player.admin then _count=_count+1 end - end - return _count -end - ---- used to get the number of afk players defined by 2 min by default --- @usage Sync.count_afk() --- @tparam[opt=7200] int time in ticks that a player is called afk --- @treturn int the number of afk players -function Sync.count_afk_times(time) - if not game then return 0 end - local time = time or 7200 - local rtn = {} - for _,player in pairs(game.connected_players) do - if player.afk_time > time then rtn[player.name] = Sync.tick_format(player.afk_time) end - end - return rtn -end - ---- used to get the number of players in each rank and currently online --- @usage Sync.count_ranks() --- @treturn table contains the ranks and the players in that rank -function Sync.count_ranks() - if not game then return {'Offline'} end - local _ranks = {} - for power,rank in pairs(Ranking._ranks()) do - local players = rank:get_players() - for k,player in pairs(players) do players[k] = player.name end - local online = rank:get_players(true) - for k,player in pairs(online) do online[k] = player.name end - _ranks[rank.name] = {players=players,online=online,n_players=#players,n_online=#online} - end - return _ranks -end - ---- used to get the number of players either online or all --- @usage Sync.count_players() --- @tparam bolean online if true only get online players --- @treturn table contains player names -function Sync.count_players(online) - if not game then return {'Offline'} end - local _players = {} - local players = {} - if online then _players = game.connected_players else _players = game.players end - for k,player in pairs(_players) do table.insert(players,player.name) end - return players -end - ---- used to get the number of players resulting in there play times --- @usage Sync.count_player_times() --- @treturn table contains players and each player is given a tick amount and a formated string -function Sync.count_player_times() - if not game then return {'Offline'} end - local _players = {} - for index,player in pairs(game.players) do - _players[player.name] = Sync.tick_format(player.online_time) - end - return _players -end - ---- used to return the global list and set values in it --- @usage Sync.info{server_name='Factorio Server 2'} --- @tparam[opt=nil] table keys to be replaced in the server info --- @return either returns success when setting or the info when not setting -function Sync.info(set) - if not global.exp_core then global.exp_core = {} end - if not global.exp_core.sync then global.exp_core.sync = { - server_name='Factorio Server', - server_description='A factorio server for everyone', - reset_time='On Demand', - time='Day Mth 00 00:00:00 UTC Year', - game_speed=game.speed, - time_set=Sync.tick_format(0), - last_update=Sync.tick_format(0), - time_period=Sync.tick_format(18000), - players={ - online=Sync.count_players(true), - n_online=#game.connected_players, - all=Sync.count_players(), - n_all=#game.players, - admins_online=Sync.count_admins(), - afk_players=Sync.count_afk_times(), - times=Sync.count_player_times() - }, - ranks=Sync.count_ranks(), - rockets=game.forces['player'].get_item_launched('satellite'), - mods={'base'} - } end - if not set then return global.exp_core.sync - else - if not is_type(set,'table') then return false end - for key,value in pairs(set) do - global.exp_core.sync[key] = value - end - return true - end -end - ---- used to return the global time and set its value --- @usage Sync.time('Sun Apr 1 18:44:30 UTC 2018') --- @tparam[opt=nil] string the date time to be set --- @return either true false if setting or the date time and tick off set -function Sync.time(set) - local info = Sync.info() - if not set then return info.time..' (+'..(game.tick-info.time_set[1])..' Ticks)' - else - if not is_type(set,'string') then return false end - info.time = set - info.time_set[1] = game.tick - info.time_set[2] = tick_to_display_format(game.tick) - return true - end -end - ---- called to update values inside of the info --- @usage Sync.update() --- @return all of the new info -function Sync.update() - local info = Sync.info() - info.time_period[2] = tick_to_display_format(info.time_period[1]) - info.last_update[1] = game.tick - info.last_update[2] = tick_to_display_format(game.tick) - info.game_speed=game.speed - info.players={ - online=Sync.count_players(true), - n_online=#game.connected_players, - all=Sync.count_players(), - n_all=#game.players, - admins_online=Sync.count_admins(), - afk_players=Sync.count_afk_times(), - times=Sync.count_player_times() - } - info.ranks = Sync.count_ranks() - info.rockets = game.forces['player'].get_item_launched('satellite') - for key,callback in pairs(Sync_updates) do info[key] = callback() end - return info -end - ---- Adds a callback to be called when the info is updated --- @usage Sync.add_update('players',function() return #game.players end) --- @tparam key string the key that the value will be stored in --- @tparam callback function the function which will return this value -function Sync.add_update(key,callback) - if game then return end - if not is_type(callback,'function') then return end - Sync_updates[key] = callback -end - ---- outputs the curent server info into a file --- @usage Sync.emit_data() -function Sync.emit_data() - local info = Sync.info() - game.write_file('server-info.json',table.json(info),false,0) -end - --- will auto replace the file every 5 min by default -Event.register(defines.events.on_tick,function(event) - local time = Sync.info().time_period[1] - if (event.tick%time)==0 then Sync.update() Sync.emit_data() end -end) - ---- Adds a emeltent to the sever info gui --- @usage Sync.add_to_gui('string') -- return trues --- @param element see examples before for what can be used, it can also be a return from Gui.inputs.add --- @treturn bolean based on weather it was successful or not -function Sync.add_to_gui(element,...) - if game then return false end - if is_type(element,'function') then - table.insert(Sync_gui_functions,{'function',element,...}) - elseif is_type(element,'table') then - if element.draw then table.insert(Sync_gui_functions,{'gui',element}) - else table.insert(Sync_gui_functions,{'table',element}) end - else table.insert(Sync_gui_functions,{'string',element}) end - return true -end - --- Examples for Sync.add_to_gui --- adds a basic string to the table -Sync.add_to_gui('Welcome to the Explosive Gaming comunity! This is one of many servers which we host.') --- adds a string that can have depentant values -Sync.add_to_gui(function(player,frame) - return 'You have been assigned the rank \''..Ranking.get_rank(player).name..'\'' -end) -Sync.add_to_gui(function(player,frame) - return 'This server\'s next reset: '..Sync.info().reset_time -end) --- if readme is included then see addons/guis/readme.lua for more examples - --- used to load the gui infomation when _G.Gui is not yet loaded --- internal use not recomend to be used -function Sync._load() - local function label_format(label,width) - label.style.width = width - label.style.align = 'center' - label.style.single_line = false - end - Gui.center.add{ - name='server-info', - caption='Server Info', - tooltip='Basic info about the current server', - draw=function(self,frame) - frame.caption = '' - local info = Sync.info() - local frame = frame.add{type='flow',direction='vertical'} - local _flow = frame.add{type='flow'} - Gui.bar(_flow,200) - label_format(_flow.add{ - type='label', - caption='Welcome To '..info.server_name, - style='caption_label' - },180) - Gui.bar(_flow,200) - label_format(frame.add{ - type='label', - caption=info.server_description,style='description_label' - },600) - Gui.bar(frame,600) - local _frame = frame - local frame = frame.add{ - type='frame', - direction='vertical', - style='image_frame' - } - frame.style.width = 600 - local text_flow = frame.add{type='flow',direction='vertical'} - local button_flow = frame.add{type='table',column_count=3} - for _,element in pairs(table.deepcopy(Sync_gui_functions)) do - local _type = table.remove(element,1) - if _type == 'function' then - local success, err = pcall(table.remove(element,1),frame.player_index,frame,unpack(element)) - if not success then error(err) else - if is_type(err,'table') then - if element.draw then element:draw(button_flow).style.width = 195 - else label_format(text_flow.add{type='label',caption=err},585) end - else label_format(text_flow.add{type='label',caption=tostring(err)},585) end - end - elseif _type == 'gui' then element[1]:draw(button_flow).style.width = 195 - elseif _type == 'string' then label_format(text_flow.add{type='label',caption=tostring(element[1])},585) - elseif _type == 'table' then label_format(text_flow.add{type='label',caption=element[1]},585) end - end - _frame.add{ - type='label', - caption='Press Esc or E to close; this is only visible once!', - style='fake_disabled_label' - }.style.font='default-small' - end} -end - --- opens the server info gui for all new joins except admins -Event.register(defines.events.on_player_joined_game,function(event) - local player = Game.get_player(event) - Gui.center.open(player,'server-info') -end) - -return Sync diff --git a/ExpLib.lua b/ExpLib.lua deleted file mode 100644 index 7c6751f0..00000000 --- a/ExpLib.lua +++ /dev/null @@ -1,126 +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----------------------------------------------------------- - --- @module ExpLib --- @usage require('/ExpLib') - -local ExpLib = {} ---- Loads a table into the global lua table --- @usage a = {k1='foo',k2='bar'} --- _load_to_G(a) --- @tparam table tbl table to add to the global lua table -function ExpLib._unpack_to_G(tbl) - if not type(tbl) == 'table' or game then return end - for name,value in pairs(tbl) do - if not _G[name] then _G[name] = value end - end -end - ---- Returns a bolean based on the type of v matching the test type --- @usage a = 'foo' --- is_type(a,'string') -- return true --- @param v the value to be tested --- @tparam[opt=nil] string test_type the type to test for if nil then it tests for nil --- @treturn bolean is v a matching type -function ExpLib.is_type(v,test_type) - return test_type and v and type(v) == test_type or not test_type and not v or false -end - ---- Returns a value to the player or if no player then log the return --- @usage a = 'to return' --- player_return(a) --- @param rtn the value to return --- @param player the player to print to -function ExpLib.player_return(rtn,colour,player) - local colour = colour or defines.color.white - local player = player or game.player - if player then - local player = Game.get_player(player) - if not player then return end - player.play_sound{path='utility/scenario_message'} - if is_type(rtn,'table') then - -- test if its a localised string - if is_type(rtn.__self,'userdata') then player.print('Cant Display Userdata',colour) - elseif is_type(rtn[1],'string') and string.find(rtn[1],'.+[.].+') and not string.find(rtn[1],'%s') then pcall(player.print,rtn,colour) - else player.print(table.to_string(rtn),colour) - end - elseif is_type(rtn,'function') then player.print('Cant Display Functions',colour) - else player.print(tostring(rtn),colour) - end - else - local _return = 'Invalid' - if is_type(rtn,'table') then _return = table.to_string(rtn) - elseif is_type(rtn,'function') then _return = 'Cant Display Functions' - elseif is_type(rtn,'userdata') then _return = 'Cant Display Userdata' - else _return = tostring(rtn) - end log(_return) rcon.print(_return) - end -end - ---- Convert ticks to hours --- @usage a = 216001 --- tick_to_hour(a) -- return 1 --- @tparam number tick to convert to hours --- @treturn number the number of whole hours from this tick -function ExpLib.tick_to_hour(tick) - if not is_type(tick,'number') then return 0 end - return math.floor(tick/(216000*game.speed)) -end - ---- Convert ticks to minutes --- @usage a = 3601 --- tick_to_hour(a) -- return 1 --- @tparam number tick to convert to minutes --- @treturn number the number of whole minutes from this tick -function ExpLib.tick_to_min (tick) - if not is_type(tick,'number') then return 0 end - return math.floor(tick/(3600*game.speed)) -end - ---- Returns a tick in a displayable format --- @usage a = 3600 --- tick_to_display_format(a) -- return '1.00 M' --- @usage a = 234000 --- tick_to_display_format(a) -- return '1 H 5 M' --- @tparam number tick to convert --- @treturn string the formated string -function ExpLib.tick_to_display_format(tick) - if not is_type(tick,'number') then return '0H 0M' end - if tick_to_min(tick) < 10 then - return string.format('%.2f M',tick/(3600*game.speed)) - else - return string.format('%d H %d M', - tick_to_hour(tick), - tick_to_min(tick)-60*tick_to_hour(tick) - ) - end -end - -function ExpLib.Gui_tree(root) - local tree = {} - for _,child in pairs(root.children) do - if #child.children > 0 then - if child.name then - tree[child.name] = ExpLib.Gui_tree(child) - else - table.insert(tree,ExpLib.Gui_tree(child)) - end - else - if child.name then - tree[child.name] = child.type - else - table.insert(tree,child.type) - end - end - end - return tree -end - -return ExpLib \ No newline at end of file diff --git a/Factorio-luacheckrc b/Factorio-luacheckrc new file mode 160000 index 00000000..0c0518d1 --- /dev/null +++ b/Factorio-luacheckrc @@ -0,0 +1 @@ +Subproject commit 0c0518d165b0fcee714f9e00b014afd7aba9fbee diff --git a/FactorioSoftmodManager.lua b/FactorioSoftmodManager.lua new file mode 100644 index 00000000..3b7cc1a7 --- /dev/null +++ b/FactorioSoftmodManager.lua @@ -0,0 +1,754 @@ +--- Factorio Softmod Manager +-- @module FSM +-- @alias Manager +-- @author Cooldude2606 +-- @usage Manager = require("FactorioSoftmodManager") +local moduleIndex = require("/modules/index") +local Manager = {} + +-- this is a constant that is used to represent the server +SERVER = setmetatable({index=0,name='',online_time=0,afk_time=0,print=print,admin=true,valid=true,__self={}},{__index=function(tbl,key) if type(game.players[1][key]) == 'function' then return function() end else return nil end end}) + +--- Setup for metatable of the Manager to force read only nature +-- @usage Manager() -- runs Manager.loadModdules() +-- @usage Manager[name] -- returns module by that name +-- @usage tostring(Manager) -- returns formated list of loaded modules +local ReadOnlyManager = setmetatable({},{ + __metatable=false, + __index=function(tbl,key) + -- first looks in manager and then looks in mander.loadModules + return rawget(Manager,key) ~= nil and rawget(Manager,key) or rawget(Manager.loadModules,key) + end, + __call=function(tbl) + -- if there are no modules loaded then it loads them + if #tbl.loadModules == 0 then + tbl.loadModules() + end + end, + __newindex=function(tbl,key,value) + -- provents the changing of any key that is not currentState + if key == 'currentState' then + -- provides a verbose that is always emited describing the change in state + Manager.verbose(string.rep('__',10)..'| Start: '..value..' |'..string.rep('__',10),true) + Manager.verbose('The verbose state is now: '..tostring(Manager.setVerbose[value]),true) + rawset(Manager,key,value) + else error('Manager is read only please use included methods',2) end + end, + __tostring=function(tbl) + -- acts as a redirect + return tostring(Manager.loadModules) + end +}) + +local function setupModuleName(name) + -- creates a table that acts like a string but is read only + return setmetatable({},{ + __index=function(tbl,key) return name end, + __newindex=function(tbl,key,value) error('Module Name Is Read Only') end, + __tostring=function(tbl) return name end, + __concat=function(val1,val2) return type(val1) == 'string' and val1..name or name..val2 end, + __metatable=false, + }) +end + +Manager.currentState = 'selfInit' +-- selfInit > moduleLoad > moduleInit > modulePost > moduleEnv + +--- Default output for the verbose +-- @usage Manager.verbose('Hello, World!') +-- @tparam string rtn the value that will be returned though verbose output +Manager._verbose = function(rtn) + -- creates one file per game, ie clears file on reset + if game and Manager.setVerbose._output ~= true then Manager.setVerbose._output=true game.write_file('verbose.log',rtn) + elseif game then game.write_file('verbose.log','\n'..rtn,true) end + -- standard print and log, _log is a version of log which is ln1 of control.lua for shorter log lines + if print then print(rtn) end + if _log then _log(rtn) end +end + +--- Used to call the output of the verbose when the current state allows it +-- @usage Manager.verbose('Hello, World!') +-- @tparam string rtn the value that will be returned though verbose output +-- @tparam string action is used to decide which verbose this is error || event etc +Manager.verbose = function(rtn,action) + local settings = Manager.setVerbose + local state = Manager.currentState + if Manager.error and state == Manager.error.__crash then return end + -- if ran in a module the the global moduleName is present + local rtn = type(rtn) == table and serpent.line(rtn) or tostring(rtn) + if moduleName then rtn='['..moduleName..'] '..rtn + else rtn='[FSM] '..rtn end + -- module_verbose is a local override for a file, action is used in the manager to describe an extra type, state is the current state + -- if action is true then it will always trigger verbose + if module_verbose or (action and (action == true or settings[action])) or (not action and settings[state]) then + if type(settings.output) == 'function' then + -- calls the output function, not pcalled as if this fails some thing is very wrong + settings.output(rtn) + else + error('Verbose set for: '..state..' but output can not be called',2) + end + end +end + +--- Main logic for allowing verbose at different stages though out the script +-- @function Manager.setVerbose +-- @usage Manager.setVerbose{output=log} +-- @tparam newTbl settings the table that will be searched for settings to be updated +-- @usage Manager.setVerbose[setting] -- returns the value of that setting +-- @usage tostring(Manager.setVerbose) -- returns a formated list of the current settings +Manager.setVerbose = setmetatable( + --- Different verbose settings used for setVerbose + -- @table Manager.verboseSettings + -- @tfield boolean selfInit called while the manager is being set up + -- @tfield boolean moduleLoad when a module is required by the manager + -- @tfield boolean moduleInit when and within the initation of a module + -- @tfield boolean modulePost when and within the post of a module + -- @tfield boolean moduleEnv during module runtime, this is a global option set within each module(module_verbose=true ln:1) for fine control + -- @tfield boolean eventRegistered when a module registers its event handlers + -- @tfield boolean errorCaught when an error is caught during runtime + -- @tfield function output can be: print || log || or other function + -- @field _output a constant value that can used to store output data + { + selfInit=true, + moduleLoad=false, + moduleInit=false, + modulePost=false, + moduleEnv=false, + eventRegistered=false, + errorCaught=true, + output=Manager._verbose, + _output={} + }, + { + __metatable=false, + __call=function(tbl,settings) + -- does not allow any new keys, but will override any existing ones + for key,value in pairs(settings) do + if rawget(tbl,key) ~= nil then + Manager.verbose('Verbose for: "'..key..'" has been set to: '..tostring(value)) + rawset(tbl,key,value) + end + end + end, + __newindex=function(tbl,key,value) + -- stops creationg of new keys + error('New settings cannot be added during runtime',2) + end, + __index=function(tbl,key) + -- will always return a value, never nil + return rawget(tbl,key) or false + end, + __tostring=function(tbl) + -- a simple concat function for the settings + local rtn = '' + for key,value in pairs(tbl) do + if type(value) == 'boolean' then + rtn=rtn..key..': '..tostring(value)..', ' + end + end + return rtn:sub(1,-3) + end + } +) +-- call to verbose to show start up, will always be present +Manager.verbose(string.rep('__',10)..'| Start: selfInit |'..string.rep('__',10),true) +Manager.verbose('The verbose state is: '..tostring(Manager.setVerbose.selfInit),true) + +--- Used to avoid conflicts in the global table +-- @usage global[key] -- used like the normal global table +-- @usage global{'foo','bar'} -- sets the default value +-- @usage global(true) -- restores global to default +-- @usage global(mopdule_name) -- returns that module's global +-- @tparam[opt={}] ?table|string|true if table then the default for the global, if a string then the module to get the global of, if true then reset the global to default +-- @treturn table the new global table for that module +Manager.global=setmetatable({__defaults={},__global={ + __call=function(tbl,default) return Manager.global(default) end, + __index=function(tbl,key) return rawget(Manager.global(),key) or tbl(key) end, + __newindex=function(tbl,key,value) rawset(Manager.global(),key,value) end, + __pairs=function(tbl) + local tbl = Manager.global() + local function next_pair(tbl,k) + k, v = next(tbl, k) + if type(v) ~= nil then return k,v end + end + return next_pair, tbl, nil + end +}},{ + __call=function(tbl,default,metatable_src) + -- creates varible link to global and module information, use of a metatable is for already formed globals + local Global = _G.global + local metatable = getmetatable(metatable_src) + local moduleName = type(default) == 'string' and default or metatable and metatable._moduleName or moduleName + local module_path = type(default) == 'string' and Manager.loadModules.__load[default] or metatable and metatable._module_path or module_path + -- if there is no name or path then it will return and unedited version of global + if not module_path or not moduleName then return _G.global end + -- edits the link to global to be the corrected dir, path varible is also created + local path = 'global' + for dir in module_path:gmatch('%a+') do + path = path..'.'..dir + if not rawget(Global,dir) then Manager.verbose('Added Global Dir: '..path) rawset(Global,dir,{}) end + Global = rawget(Global,dir) + end + -- the default value is set if there was a default given + if type(default) == 'table' then Manager.verbose('Default global has been set for: global'..string.sub(module_path:gsub('/','.')),2) rawset(rawget(tbl,'__defaults'),tostring(moduleName),default) end + -- if the default value is true then it will reset the global to its default + if default == true and rawget(rawget(tbl,'__defaults'),tostring(moduleName)) then + Manager.verbose('Reset Global Dir to default: '..path) + -- cant set it to be equle otherwise it will lose its global propeity + local function deepcopy(tbl) if type(tbl) ~= 'table' then return tbl end local rtn = {} for key,value in pairs(tbl) do rtn[key] = deepcopy(value) end return rtn end + for key,value in pairs(Global) do rawset(Global,key,nil) end + for key,value in pairs(rawget(rawget(tbl,'__defaults'),tostring(moduleName))) do rawset(Global,key,deepcopy(value)) end + end + -- the metatable is remade if not already present + metatable = metatable or { + __call=function(tbl,default) return Manager.global(default,tbl) end, + __index=function(tbl,key) return rawget(Manager.global(nil,tbl),key) or moduleIndex[key] and Manager.global(key) end, + __newindex=function(tbl,key,value) rawset(Manager.global(nil,tbl),key,value) end, + __pairs=function(tbl) + local tbl = Manager.global(nil,tbl) + local function next_pair(tbl,k) + k, v = next(tbl, k) + if type(v) ~= nil then return k,v end + end + return next_pair, tbl, nil + end, + _module_path=module_path,_moduleName=moduleName + } + return setmetatable(Global,metatable) + end, + __index=function(tbl,key) return rawget(tbl(),key) or rawget(_G.global,key) or moduleIndex[key] and Manager.global(key) end, + __newindex=function(tbl,key,value) rawset(tbl(),key,value) end, + __pairs=function(tbl) + local tbl = Manager.global() + local function next_pair(tbl,k) + k, v = next(tbl, k) + if type(v) ~= nil then return k,v end + end + return next_pair, tbl, nil + end +}) +setmetatable(global,Manager.global.__global) + +--- Creates a sand box envorment and runs a callback in that sand box; provents global pollution +-- @function Manager.sandbox +-- @usage Manager.sandbox(callback) -- return sandbox, success, other returns from callback +-- @tparam function callback the function that will be ran in the sandbox +-- @param[opt] env any other params that the function will use +-- @usage Manager.sandbox() -- returns and empty sandbox +-- @usage Manager.sandbox[key] -- returns the sand box value in that key +Manager.sandbox = setmetatable({ + -- can not use existing keys of _G + verbose=Manager.verbose, + loaded_modules={}, -- this is over riden later + module_verbose=false, + module_exports=false, + _no_error_verbose=true +},{ + __metatable=false, + __index=ReadOnlyManager, + __call=function(tbl,callback,env,...) + if type(callback) == 'function' then + -- creates a new sandbox env + local sandbox = tbl() + local env = type(env) == 'table' and env or {} + local _G_mt = getmetatable(_G) + -- creates a new ENV where it will look in the provided env then the sand box and then _G, new indexes saved to sandbox + local tmp_env = setmetatable({},{__index=function(tbl,key) return env[key] or sandbox[key] or rawget(_G,key) end,newindex=sandbox}) + tmp_env._ENV = tmp_env + tmp_env._G_mt = _G_mt + -- sets the upvalues for the function + local i = 1 + while true do + local name, value = debug.getupvalue(callback,i) + if not name then break else if not value and tmp_env[name] then debug.setupvalue(callback,i,tmp_env[name]) end end + i=i+1 + end + -- runs the callback + setmetatable(_G,{__index=tmp_env,newindex=sandbox}) + local rtn = {pcall(callback,...)} + local success = table.remove(rtn,1) + setmetatable(_G,_G_mt) + -- this is to allow modules to be access with out the need of using Mangaer[name] also keeps global clean + if success then return success, rtn, sandbox + else return success, rtn[1], sandbox end + else return setmetatable({},{__index=tbl}) end + end +}) + +--- Allows access to modules via require and collections are returned as one object +-- @function Manager.require +-- @usage local Module = Manager.require(ModuleName) +-- @usage local Module = Manager.require[ModuleName] +-- @usage local SrcData = Manager.require(path) +-- @treturn table the module that was required, one object containg submodules for a +Manager.require = setmetatable({ + __require=require +},{ + __metatable=false, + __index=function(tbl,key) return tbl(key,nil,true) end, + __call=function(tbl,path,env,mute,noLoad) + local raw_require = rawget(tbl,'__require') + local env = env or {} + -- runs in a sand box becuase sandbox everything + local success, data = Manager.sandbox(raw_require,env,path) + -- if there was no error then it assumed the path existed and returns the data + if success then return unpack(data) + else + if type(path) ~= 'string' then error('Path supplied must be a string; got: '..type(path),2) return end + local override = {} + local softmod = override + local path = path:find('@') and path:sub(1,path:find('@')-1) or path + -- tries to load the module from the modeul index + if moduleIndex[path] and not noLoad or Manager.loadModules.__load[path] then softmod = Manager.loadModules[path] end + -- will then look for any submodules if there are any; only once every module is loaded + for moduleName,subpath in pairs(moduleIndex) do + if moduleName:find(path) == 1 and moduleName ~= path then + local start, _end = moduleName:find(path) + local subname = moduleName:sub(_end+2) + -- does not add the module if it is a subsubmodule; or the key already exitsts + if not softmod then softmod = {} end + if not subname:find('.',nil,true) and not softmod[subname] then softmod[subname] = Manager.require(moduleName,nil,true,true) end + end + end + -- if there is any keys in the softmod it is returned else the errors with the require error + if override ~= softmod then return softmod end + if mute then return false else error(data,2) end + end + end +}) +require = Manager.require + +--- Loads the modules that are present in the index list +-- @function Manager.loadModules +-- @usage Manager.loadModules() -- loads all moddules in the index list +-- @usage #Manager.loadModules -- returns the number of modules loaded +-- @usage tostring(Manager.loadModules) -- returns a formatted list of all modules loaded +-- @usage pairs(Manager.loadModules) -- loops over the loaded modules moduleName, module +Manager.loadModules = setmetatable({ + __load=setmetatable({},{__call=function(self,moduleName) + -- check to provent multiple calls + if self[moduleName] then return end + self[moduleName] = true + self = Manager.loadModules + -- loads the module and its dependices if there are not loaded + local load = moduleIndex[moduleName] + if not load then return end + local path = table.remove(load,1) + Manager.verbose('Loading module: "'..moduleName..'"; path: '..path) + -- loads the parent module + if moduleName:find('.',nil,true) then + local revModuleName = moduleName:reverse() + local start, _end = revModuleName:find('.',nil,true) + local parentName = revModuleName:sub(_end+1):reverse() + Manager.verbose('Loading module parent: "'..parentName..'" for: "'..moduleName..'"; path: '..path) + self.__load(parentName) + end + -- loads the dependices + Manager.verbose('Loading module dependices for: "'..moduleName..'"; path: '..path) + for _,depName in pairs(load) do self.__load(depName) end + self.__load[moduleName] = path + -- runs the module in a sandbox env + local success, module, sandbox = Manager.sandbox(Manager.require.__require,{moduleName=setupModuleName(moduleName),module_path=path},path..'/control') + -- extracts the module into a global index table for later use + if success then + -- verbose to notifie of any globals that were attempted to be created + local globals = '' + for key,value in pairs(sandbox) do globals = globals..key..', ' end + if globals ~= '' then Manager.verbose('Globals caught in "'..moduleName..'": '..globals:sub(1,-3),'errorCaught') end + Manager.verbose('Successfully loaded: "'..moduleName..'"; path: '..path) + -- if it is not a table or nil then it will set up a metatable on it + local currentType = type(rawget(self,moduleName)) + if currentType ~= 'nil' and currentType ~= 'table' then + -- if it is a function then it is still able to be called even if more keys are going to be added + -- if it is a string then it will act like one; if it is a number well thats too many metatable indexs + self[moduleName] = setmetatable({__old=self[moduleName]},{ + __call=function(self,...) if type(self.__old) == 'function' then self.__old(...) else return self.__old end end, + __tostring=function(self) return self.__old end, + __concat=function(self,val) return self.__old..val end + }) + end + -- if you prefere module_exports can be used rather than returning the module + local appendAs = sandbox.module_exports or table.remove(module,1) + if not self[moduleName] then self[moduleName] = appendAs -- if nil it just sets the value + else for key,value in pairs(appendAs) do self[moduleName][key] = value end end -- else it appends the new values + -- if there is a module by this name in _G ex table then it will be indexed to the new module + if rawget(_G,moduleName) and type(rawget(self,moduleName)) == 'table' then setmetatable(rawget(_G,moduleName),{__index=self[moduleName]}) end + if type(rawget(self,moduleName)) == 'table' then self[moduleName]._module_path = path self[moduleName]._moduleName = moduleName end + -- loads the submodule for this softmod + Manager.verbose('Loading submodules for: "'..moduleName..'"; path: '..path) + for subModName,_ in pairs(moduleIndex) do + if subModName:find(moduleName) == 1 and subModName ~= moduleName then self.__load(subModName) end + end + else + Manager.verbose('Failed load: "'..moduleName..'"; path: '..path..' ('..module..')','errorCaught') + for event_name,callbacks in pairs(Manager.event) do Manager.verbose('Removed Event Handler: "'..moduleName..'/'..Manager.event.names[event_name],'eventRegistered') callbacks[moduleName] = nil end + end + end}), + __init=setmetatable({},{__call=function(self,moduleName) + -- check to provent multiple calls + if self[moduleName] or not Manager.loadModules.__load[moduleName] then return end + self[moduleName] = true + self = Manager.loadModules + -- calls on_init for each module + -- looks for init so that init or on_init can be used + local data = self[moduleName] + if type(data) == 'table' and data.init and data.on_init == nil then data.on_init = data.init data.init = nil end + if type(data) == 'table' and data.on_init and type(data.on_init) == 'function' then + Manager.verbose('Initiating module: "'..moduleName..'"') + local success, err = Manager.sandbox(data.on_init,{moduleName=setupModuleName(moduleName),module_path=Manager.loadModules.__load[tostring(moduleName)]},data) + if success then + Manager.verbose('Successfully Initiated: "'..moduleName..'"') + else + Manager.verbose('Failed Initiation: "'..moduleName..'" ('..err..')','errorCaught') + end + -- clears the init function so it cant be used in runtime + data.on_init = nil + end + end}), + __post=setmetatable({},{__call=function(self,moduleName) + -- check to provent multiple calls + if self[moduleName] or not Manager.loadModules.__init[moduleName] then return end + self[moduleName] = true + self = Manager.loadModules + -- calls on_post for each module + -- looks for post so that post or on_post can be used + local data = self[moduleName] + if type(data) == 'table' and data.post and data.on_post == nil then data.on_post = data.post data.post = nil end + if type(data) == 'table' and data.on_post and type(data.on_post) == 'function' then + Manager.verbose('Post for module: "'..moduleName..'"') + local success, err = Manager.sandbox(data.on_post,{moduleName=setupModuleName(moduleName),module_path=Manager.loadModules.__load[tostring(moduleName)]},data) + if success then + Manager.verbose('Successful post: "'..moduleName..'"') + else + Manager.verbose('Failed post: "'..moduleName..'" ('..err..')','errorCaught') + end + -- clears the post function so it cant be used in runtime + data.on_post = nil + end + end}) + }, + { + __metatable=false, + __index=function(self,moduleName) + -- will load one module if it is not already loaded, will not init during load state or post + self.__load(moduleName) + if (ReadOnlyManager.currentState == 'moduleLoad') then return end + self.__init(moduleName) + if (ReadOnlyManager.currentState == 'moduleInit') then return end + self.__post(moduleName) + return rawget(self,moduleName) + end, + __call=function(self) + -- goes though the index looking for modules to load + ReadOnlyManager.currentState = 'moduleLoad' + for moduleName,path in pairs(moduleIndex) do self.__load(moduleName) end + -- runs though all loaded modules looking for on_init function; all other modules have been loaded use this to load extra code based on opttial dependies + ReadOnlyManager.currentState = 'moduleInit' + for moduleName,path in pairs(self) do + if moduleName ~= '__load' and moduleName ~= '__init' and moduleName ~= '__post' then self.__init(moduleName) end + end + -- runs though all loaded modules looking for on_post function; all other modules have been loaded and inited, do not load extra code in this time only altar your own data + ReadOnlyManager.currentState = 'modulePost' + for moduleName,path in pairs(self) do + if moduleName ~= '__load' and moduleName ~= '__init' and moduleName ~= '__post' then self.__post(moduleName) end + end + ReadOnlyManager.currentState = 'moduleEnv' + end, + __len=function(tbl) + -- counts the number of loaded modules + local rtn = 0 + for key,value in pairs(tbl) do + rtn = rtn + 1 + end + return rtn-3 + end, + __tostring=function(tbl) + -- a concat of all the loaded modules + local rtn = 'Load Modules: ' + for key,value in pairs(tbl) do + if key ~= '__load' and key ~= '__init' and key ~= '__post' then rtn=rtn..key..', ' end + end + return rtn:sub(1,-3) + end + } +) +Manager.sandbox.loaded_modules = Manager.loadModules + +--- A more detailed replacement for the lua error function to allow for handlers to be added; repleaces default error so error can be used instead of Manager.error +-- @function Manager.error +-- @usage Manager.error(err) -- calls all error handlers that are set or if none then prints to game and if that fails crashs game +-- @usage Manager.error() -- returns an error constant that can be used to crash game +-- @usage Manager.error(Manager.error()) -- crashs the game +-- @usage Manager.error.addHandler(name,callback) -- adds a new handler if handler returns Manager.error() then game will crash +-- @tparam[2] ?string|fucntion err the string to be passed to handlers; if a function it will register a handler +-- @tparam[2] function callback if given the err param will be used to given the handler a name +-- @usage Manager.error[name] -- returns the handler of that name if present +-- @usage #Manager.error -- returns the number of error handlers that are present +-- @usage pairs(Manager.error) -- loops over only the error handlers handler_name,hander +Manager.error = setmetatable({ + __crash=false, + __error_call=error, + __error_const={}, + __error_handler=function(handler_name,callback) + -- when handler_name is a string it is expeced that callback is a function; other wise handler_name must be a function + if type(handler_name) == 'string' and type(callback) == 'function' then Manager.error[handler_name]=callback + elseif type(handler_name) == 'function' then table.insert(Manager.error,handler_name) + else Manager.error('Handler is not a function',2) end + end, + in_pcall=function(level) + local level = level and level+1 or 2 + while true do + if not debug.getinfo(level) then return false end + if debug.getinfo(level).name == 'pcall' then return level end + level=level+1 + end + end +},{ + __metatalbe=false, + __call=function(tbl,err,...) + -- if no params then return the error constant + if err == nil then return rawget(tbl,'__error_const') end + -- if the error constant is given crash game + if err == rawget(tbl,'__error_const') then Manager.verbose('Force Crash','errorCaught') rawset(tbl,'__crash',true) rawget(tbl,'__error_call')('Force Crash',2) end + -- other wise treat the call as if its been passed an err string + if not _no_error_verbose or Manager.currentState ~= 'moduleEnv' then Manager.verbose('An error has occurred: '..err,'errorCaught') end + if #tbl > 0 then + -- there is at least one error handler loaded; loops over the error handlers + for handler_name,callback in pairs(tbl) do + local success, err = pcall(callback,err,...) + if not success then Manager.verbose('Error handler: "'..handler_name..'" failed to run ('..err..')','errorCaught') end + -- if the error constant is returned from the handler then crash the game + if err == rawget(tbl,'__error_const') then Manager.verbose('Force Stop by: '..handler_name,'errorCaught') rawset(tbl,'__crash',true) rawget(tbl,'__error_call')('Force Stop by: '..handler_name) end + end + elseif game then + -- there are no handlers loaded so it will print to the game if loaded + Manager.verbose('No error handlers loaded; Default game print used','errorCaught') + game.print(err) + else + -- all else fails it will crash the game with the error code + Manager.verbose('No error handlers loaded; Game not loaded; Forced crash: '..err,'errorCaught') + rawset(tbl,'__crash',true) + rawget(tbl,'__error_call')(err,2) + end + local args = {...} + local trace = args[1] and type(args[1]) == 'number' and args[1]+1 or 2 + if tbl.in_pcall(2) then rawget(tbl,'__error_call')(err,trace) end + end, + __index=function(tbl,key) + -- this allows the __error_handler to be called from many different names + if type(key) ~= 'string' then return end + if key:lower() == 'addhandler' or key:lower() == 'sethandler' or key:lower() == 'handler' or key:lower() == 'register' then return rawget(tbl,'__error_handler') + else rawget(tbl,'__error_call')('Invalid index for error handler; please use build in methods.') end + end, + __newindex=function(tbl,key,value) + -- making a new index adds it as a handler + if type(value) == 'function' then + Manager.verbose('Added Error Handler: "'..key..'"','eventRegistered') + rawset(tbl,key,value) + end + end, + __len=function(tbl) + -- counts the number of handlers there are + local rtn=0 + for handler_name,callback in pairs(tbl) do + rtn=rtn+1 + end + return rtn + end, + __pairs=function(tbl) + -- will not return any of the three core values as part of pairs + local function next_pair(tbl,k) + local v + k, v = next(tbl, k) + if k == '__error_call' or k == '__error_const' or k == '__error_handler' or k == '__crash' or k == 'in_pcall' then return next_pair(tbl,k) end + if type(v) == 'function' then return k,v end + end + return next_pair, tbl, nil + end +}) +-- overrides the default error function +error=Manager.error + +-- event does work a bit differnt from error, and if event breaks error is the fallback + +--- Event handler that modules can use, each module can register one function per event +-- @function Manager.event +-- @usage Manager.event[event_name] = callback -- sets the callback for that event +-- @usage Manager.event[event_name] = nil -- clears the callback for that event +-- @usage Manager.event(event_name,callback) -- sets the callback for that event +-- @usage Manager.event[event_name] -- returns the callback for that event or the event id if not registered +-- @usage Manager.event(event_name) -- runs all the call backs for that event +-- @tparam ?int|string event_name that referes to an event +-- @tparam function callback the function that will be set for that event +-- @usage Manager.event() -- returns the stop value for the event proccessor, if returned during an event will stop all other callbacks +-- @usage #Manager.event -- returns the number of callbacks that are registered +-- @usage pairs(Manager.events) -- returns event_id,table of callbacks +Manager.event = setmetatable({ + __stop={}, + __events={}, + __event=script.on_event, + __generate=script.generate_event_name, + __get_handler=script.get_event_handler, + __raise=script.raise_event, + __init=script.on_init, + __load=script.on_load, + __config=script.on_configuration_changed, + events=defines.events, + error_cache={} +},{ + __metatable=false, + __call=function(tbl,event_name,new_callback,...) + if Manager.error.__crash then Manager.error.__error_call('No error handlers loaded; Game not loaded; Forced crash: '..tostring(Manager.error.__crash)) end + -- if no params then return the stop constant + if event_name == nil then return rawget(tbl,'__stop') end + -- if the event name is a table then loop over each value in that table + if type(event_name) == 'table' then + for key,_event_name in pairs(event_name) do tbl(_event_name,new_callback,...) end return + end + -- convert the event name to a number index + event_name = tonumber(event_name) or tbl.names[event_name] + -- if there is a callback present then set new callback rather than raise the event + if type(new_callback) == 'function' then + Manager.event[event_name] = new_callback return + end + -- other wise raise the event and call every callback; no use of script.raise_event due to override + local event_functions = tbl.__events[event_name] + if type(event_functions) == 'table' then + for moduleName,callback in pairs(event_functions) do + -- loops over the call backs and which module it is from + if type(callback) ~= 'function' then error('Invalid Event Callback: "'..event_name..'/'..moduleName..'"') end + local success, err = Manager.sandbox(callback,{moduleName=setupModuleName(moduleName),module_path=Manager.loadModules.__load[tostring(moduleName)]},new_callback,...) + if not success then + local cache = tbl.error_cache + local error_message = 'Event Failed: "'..moduleName..'/'..tbl.names[event_name]..'" ('..err..')' + if not cache[error_message] then Manager.verbose(error_message,'errorCaught') error(error_message) end + if tbl.names[event_name] == 'on_tick' then + if not cache[error_message] then cache[error_message] = {game.tick,1} end + if cache[error_message][1] >= game.tick-10 then cache[error_message] = {game.tick,cache[error_message][2]+1} + else cache[error_message] = nil end + if cache[error_message] and cache[error_message][2] > 100 then + Manager.verbose('There was an error happening every tick for 100 ticks, the event handler has been removed!','errorCaught') + event_functions[moduleName] = nil + end + end + end + -- if stop constant is returned then stop further processing + if err == rawget(tbl,'__stop') then Manager.verbose('Event Haulted By: "'..moduleName..'"','errorCaught') break end + end + end + end, + __newindex=function(tbl,key,value) + -- handles the creation of new event handlers + if type(value) ~= 'function' and type(value) ~= nil then error('Attempted to set a non function value to an event',2) end + -- checks for a global module name that is present + local moduleName = moduleName or 'FSM' + -- converts the key to a number index for the event + Manager.verbose('Added Handler: "'..tbl.names[key]..'"','eventRegistered') + -- checks that the event has a valid table to store callbacks; if its not valid it will creat it and register a real event handler + if not rawget(rawget(tbl,'__events'),key) then + if key == -1 or key == -2 then -- this already has a handler + elseif key < 0 then rawget(tbl,tbl.names[key])(function(...) tbl(key,...) end) + else rawget(tbl,'__event')(key,function(...) tbl(key,...) end) end + rawset(rawget(tbl,'__events'),key,{}) end + -- adds callback to Manager.event.__events[event_id][moduleName] + rawset(rawget(rawget(tbl,'__events'),key),tostring(moduleName),value) + end, + __index=function(tbl,key) + -- few redirect key + local redirect={register=tbl,dispatch=tbl,remove=function(event_id) tbl[event_name]=nil end} + if rawget(redirect,key) then return rawget(redirect,key) end + -- proforms different look ups depentding weather the current module has an event handler registered + if moduleName then + -- first looks for the event callback table and then under the module name; does same but converts the key to a number; no handler regisered so returns the converted event id + return rawget(rawget(tbl,'__events'),key) and rawget(rawget(rawget(tbl,'__events'),key),tostring(moduleName)) + or rawget(rawget(tbl,'__events'),rawget(tbl,'names')[key]) and rawget(rawget(rawget(tbl,'__events'),rawget(tbl,'names')[key]),tostring(moduleName)) + or rawget(tbl,'names')[key] + else + -- if there is no module present then it will return the full list of regisered handlers; or other wise the converted event id + return rawget(rawget(tbl,'__events'),key) or rawget(rawget(tbl,'__events'),rawget(tbl,'names')[key]) or rawget(tbl,'names')[key] + end + end, + __len=function(tbl) + -- counts every handler that is regised not just the the number of events with handlers + local rtn=0 + for event,callbacks in pairs(tbl) do + for module,callback in pairs(callbacks) do + rtn=rtn+1 + end + end + return rtn + end, + __pairs=function(tbl) + -- will loops over the event handlers and not Manager.event + local function next_pair(tbl,k) + k, v = next(rawget(tbl,'__events'), k) + if type(v) == 'table' then return k,v end + end + return next_pair, tbl, nil + end +}) + +--- Sub set to Manger.event and acts as a coverter between event_name and event_id +-- @table Manager.event.names +-- @usage Manager.event[event_name] +rawset(Manager.event,'names',setmetatable({},{ + __index=function(tbl,key) + if type(key) == 'number' or tonumber(key) then + -- if it is a number then it will first look in the cache + if rawget(tbl,key) then return rawget(tbl,key) end + -- if it is a core event then it will simply return + if key == -1 then rawset(tbl,key,'__init') + elseif key == -2 then rawset(tbl,key,'__load') + elseif key == -3 then rawset(tbl,key,'__config') + else + -- if it is not a core event then it does a value look up on Manager.events aka defines.events + for event,id in pairs(rawget(Manager.event,'events')) do + if id == key then rawset(tbl,key,event) end + end + end + -- returns the value from the cache after being loaded in + return rawget(tbl,key) + -- if it is a string then no reverse look up is required + else + if key == 'on_init' or key == 'init' or key == '__init' then return -1 + elseif key == 'on_load' or key == 'load' or key == '__load' then return -2 + elseif key == 'on_configuration_changed' or key == 'configuration_changed' or key == '__config' then return -3 + else return rawget(rawget(Manager.event,'events'),key) end + end + end +})) + +script.on_init(function(...) + Manager.verbose('____________________| SubStart: script.on_init |____________________') + setmetatable(global,Manager.global.__global) + local names = {} + for name,default in pairs(Manager.global.__defaults) do table.insert(names,name) end + Manager.verbose('Global Tables: '..table.concat(names,', ')) + for name,default in pairs(Manager.global.__defaults) do global(name)(true) end + Manager.event(-1,...) + Manager.verbose('____________________| SubStop: script.on_init |____________________') +end) + +script.on_load(function(...) + Manager.verbose('____________________| SubStart: script.on_load |____________________') + setmetatable(global,Manager.global.__global) + local names = {} + for name,default in pairs(Manager.global.__defaults) do table.insert(names,name) end + Manager.verbose('Global Tables: '..table.concat(names,', ')) + for name,default in pairs(Manager.global.__defaults) do Manager.verbose('Global '..name..' = '..serpent.line(Manager.global(name))) end + Manager.event(-2,...) + Manager.verbose('____________________| SubStop: script.on_load |____________________') +end) +--over rides for the base values; can be called though Event +Event=setmetatable({},{__call=Manager.event,__index=function(tbl,key) return Manager.event[key] or script[key] or error('Invalid Index To Table Event') end}) +script.mod_name = setmetatable({},{__index=_G.moduleName}) +script.on_event=Manager.event +script.raise_event=Manager.event +script.on_init=function(callback) Manager.event(-1,callback) end +script.on_load=function(callback) Manager.event(-2,callback) end +script.on_configuration_changed=function(callback) Manager.event(-3,callback) end +script.get_event_handler=function(event_name) return type(Manager.event[event_name]) == 'function' and Manager.event[event_name] or nil end +script.generate_event_name=function(event_name) local event_id = Manager.event.__generate() local event_name = event_name or event_id Manager.event.events[event_name]=event_id return event_id end +-- to do set up nth tick + +return ReadOnlyManager \ No newline at end of file diff --git a/README.md b/README.md index 2e5a019e..c63887d5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,26 @@ -## ExpGaming Repository [![CodeFactor](https://www.codefactor.io/repository/github/badgamernl/explosivegaming-main/badge)](https://www.codefactor.io/repository/github/badgamernl/explosivegaming-main) [![dev chat](https://discordapp.com/api/guilds/260843215836545025/widget.png?style=shield)](https://discord.explosivegaming.nl) +

+ logo +
+ + Release + + + Downloads + + + Star + + + Fork + + + CodeFactor + + + Discord + +

+

ExpGaming Scenario Repository

#### Using The Core Files 1. Copy the core folder and the StdLib File diff --git a/StandAlone/load.lua b/StandAlone/load.lua deleted file mode 100644 index be51306e..00000000 --- a/StandAlone/load.lua +++ /dev/null @@ -1,17 +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----------------------------------------------------------- --- this file will just contain all the diffrent requires -require('colours') -require('health') -require('spawn') -require('starting-items') -require('paths') -require('body-marker') -require('chat-popup') \ No newline at end of file diff --git a/StdLib/LICENSE b/StdLib/LICENSE deleted file mode 100644 index 3f57599c..00000000 --- a/StdLib/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -This is the license of Factorio-Stdlib: https://github.com/Afforess/Factorio-Stdlib/blob/master/LICENSE - -Copyright (c) 2016, Afforess - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/StdLib/color.lua b/StdLib/color.lua deleted file mode 100644 index 54aa9376..00000000 --- a/StdLib/color.lua +++ /dev/null @@ -1,312 +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') - -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. ---
    ---
  • If ***alpha*** is given, set `color.a` to it. ---
  • If ***alpha*** is not given, and if the given color table does not have a value for `color.a`, set `color.a` to 1. ---
  • If ***alpha*** is not given, and if the given color table already has a value for `color.a`, then leave `color.a` alone. ---
--- @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) - if not _G.Game then error('StdLib/Game not loaded') end - _G.Game.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 diff --git a/StdLib/event.lua b/StdLib/event.lua deleted file mode 100644 index 9a4a380b..00000000 --- a/StdLib/event.lua +++ /dev/null @@ -1,172 +0,0 @@ ---- Makes working with events in factorio a lot more simple. ---

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(...)

--- @module Event --- @usage require('stdlib/event/event') - -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) - if not _G.Game then error('StdLib/Game not loaded') end - _G.Game.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) - if not _G.Game then error('StdLib/Game not loaded') end - _G.Game.fail_if_missing(event, "missing event argument") - _G.Game.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 \ No newline at end of file diff --git a/StdLib/load.lua b/StdLib/load.lua deleted file mode 100644 index 0ee0dc47..00000000 --- a/StdLib/load.lua +++ /dev/null @@ -1,36 +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 - verbose('StdLib Extraction: '..name) - table.insert(_return,StdLib[name]) - end - end - return unpack(_return) -end \ No newline at end of file diff --git a/StdLib/time.lua b/StdLib/time.lua deleted file mode 100644 index b3b520cb..00000000 --- a/StdLib/time.lua +++ /dev/null @@ -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) -} diff --git a/config.ld b/config.ld new file mode 100644 index 00000000..c79db209 --- /dev/null +++ b/config.ld @@ -0,0 +1,3 @@ +new_type('command','Commands',false,'param') +new_type('event','Events',false,'field') +new_type('gui','Guis') \ No newline at end of file diff --git a/control.lua b/control.lua index 90226fbb..1c352a55 100644 --- a/control.lua +++ b/control.lua @@ -1,85 +1,14 @@ ---[[ -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----------------------------------------------------------- - --- Replaces the base error function -_error = error -error = function(err) - verbose('Error Called: '..err) - if _G.error_handle and type(error_handle) == 'function' then - verbose('Exception Caught By Error Handle') - local success, _err = pcall(error_handle,err) - if not success then _error({handle=_err,err=err}) end - elseif _G.Game and game then - verbose('Exception Caught By Game Print') - if Game.print_all(err) == 0 then - _error(err) - end - else - verbose('Failed to catch error') - _error(err) - end -end --- Replaces the base require function and verbose function -_verbose = false -- Set to true for more on the loading of the files -function verbose(str) if _verbose then log(str) print(str) end end -verbose('============================= START =============================') -require_return_err = false -- Set to false when removing files; set to true for debuging -_require = require -require = function(path) - local _path = path - if string.sub(path,1) ~= '/' then path = '/'..path end - local _return = {pcall(_require,path)} - if not table.remove(_return, 1) then - local __return = {pcall(_require,'/Addons'..path)} - if not table.remove(__return, 1) then - verbose('Failed to load: '.._path..' ('.._return[1]..')') - verbose('Also Attemped: /Addons'..path..' ('..__return[1]..')') - if require_return_err then error(unpack(_return)) end - else verbose('Loaded: '.._path) return unpack(__return) end - else verbose('Loaded: '.._path) end - return unpack(_return) -end - -verbose('Begain Base Lib Loading') -require('mod-gui') --- Loads the stdlib and allows Core Game and Event -Color, Game, Event = require('StdLib/load'){'Color','Game','Event'} - --- loads the ExpLib, functions are placed into the lua global -local ExpLib = require 'ExpLib' -verbose('ExpLib Extraction') -ExpLib._unpack_to_G(ExpLib) - -verbose('Begain Core File Loading') --- Loads the ExpCore files. These are need in order to run the other addons -Ranking, Sync, Server, Gui = require('ExpCore/load'){'Ranking','Sync','Server','Gui'} -verbose('Gui Test Initiation') -local success,err = require('ExpCore/GuiParts/test') -if success then Gui.test = err else verbose('No Test Present') end -if Gui.popup then verbose('Gui Popup Initiation') Gui.popup._load() end -if Sync._load then verbose('Sync Initiation') Sync._load() end --- Loads the ranks that Ranking uses -verbose('Base Ranks Initiation') -require('ExpCore/ranks') --- Loads any edits that are not need in core pcall as file may not be present -verbose('Extented Ranks Initiation') -require('Addons/playerRanks') --- Makes sure that all the little details are cleaned up -verbose('Ranking Initiation') -Ranking._auto_edit_ranks() --- Loads all the addons -verbose('Begain Addons Loading') -local success,err = pcall(require,'Addons/load') -if not success then error(err) end --- Loads anything that does not use ExpCore (source given in the file) -verbose('Begain Stand Alone Loading') -local success,err = pcall(require,'StandAlone/load') -if not success then error(err) end -verbose('============================== END ==============================') \ No newline at end of file +-- not_luadoc=true +function _log(...) log(...) end -- do not remove this is used for smaller verbose lines +Manager = require("FactorioSoftmodManager") +Manager.setVerbose{ + selfInit=true, -- called while the manager is being set up + moduleLoad=false, -- when a module is required by the manager + moduleInit=false, -- when and within the initation of a module + modulePost=false, -- when and within the post of a module + moduleEnv=false, -- during module runtime, this is a global option set within each module for fine control + eventRegistered=false, -- when a module registers its event handlers + errorCaught=true, -- when an error is caught during runtime + output=Manager._verbose -- can be: can be: print || log || other function +} +Manager() -- can be Manager.loadModules() if called else where \ No newline at end of file diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 00000000..f5d24cda --- /dev/null +++ b/doc/index.html @@ -0,0 +1,144 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ + + +

Modules

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FSMFactorio Softmod Manager
ExpGamingCore.CommandA full ranking system for factorio.
ExpGamingCore.GuiAdds a objective version to custom guis.
ExpGamingCore.Gui.CenterAdds a uniform preset for guis in the center of the screen which allow for different tabs to be opened
ExpGamingCore.Gui.InputsAdds a clean way of making new inputs for a gui allowing for sliders and text inputs to be hanndleded with custom events
ExpGamingCore.Gui.LeftAdds a organiser for left gui ellements which will automaticaly update there information and have open requirements
ExpGamingCore.Gui.PopupAdds a location for popups which can be dismissed by a player and created from other scripts
ExpGamingCore.Gui.TestUsed to test all gui elements and parts can be used in game via Gui.test()
ExpGamingCore.Gui.ToolbarAdds a toolbar to the top left of the screen
ExpGamingCore.RoleA full ranking system for factorio.
ExpGamingCore.ServerAdds a thread system and event listening and a admin bypass (recommend to disable /c and use optional /interface)
ExpGamingCore.SyncAllows syncing with an outside server and info panle.
ExpGamingLibAdds some common functions used though out all ExpGaming modules
StdLib.ColorA defines module for retrieving colors by name.
StdLib.GameThe game module.
StdLib.StringExtends Lua 5.2 string.
StdLib.TableExtends Lua 5.2 table.
StdLib.TimeA defines module for retrieving the number of ticks in 1 unit of time.
+ +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/ldoc.css b/doc/ldoc.css new file mode 100644 index 00000000..52c4ad2b --- /dev/null +++ b/doc/ldoc.css @@ -0,0 +1,303 @@ +/* BEGIN RESET + +Copyright (c) 2010, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.8.2r1 +*/ +html { + color: #000; + background: #FFF; +} +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { + margin: 0; + padding: 0; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +fieldset,img { + border: 0; +} +address,caption,cite,code,dfn,em,strong,th,var,optgroup { + font-style: inherit; + font-weight: inherit; +} +del,ins { + text-decoration: none; +} +li { + margin-left: 20px; +} +caption,th { + text-align: left; +} +h1,h2,h3,h4,h5,h6 { + font-size: 100%; + font-weight: bold; +} +q:before,q:after { + content: ''; +} +abbr,acronym { + border: 0; + font-variant: normal; +} +sup { + vertical-align: baseline; +} +sub { + vertical-align: baseline; +} +legend { + color: #000; +} +input,button,textarea,select,optgroup,option { + font-family: inherit; + font-size: inherit; + font-style: inherit; + font-weight: inherit; +} +input,button,textarea,select {*font-size:100%; +} +/* END RESET */ + +body { + margin-left: 1em; + margin-right: 1em; + font-family: arial, helvetica, geneva, sans-serif; + background-color: #ffffff; margin: 0px; +} + +code, tt { font-family: monospace; font-size: 1.1em; } +span.parameter { font-family:monospace; } +span.parameter:after { content:":"; } +span.types:before { content:"("; } +span.types:after { content:")"; } +.type { font-weight: bold; font-style:italic } + +body, p, td, th { font-size: .95em; line-height: 1.2em;} + +p, ul { margin: 10px 0 0 0px;} + +strong { font-weight: bold;} + +em { font-style: italic;} + +h1 { + font-size: 1.5em; + margin: 20px 0 20px 0; +} +h2, h3, h4 { margin: 15px 0 10px 0; } +h2 { font-size: 1.25em; } +h3 { font-size: 1.15em; } +h4 { font-size: 1.06em; } + +a:link { font-weight: bold; color: #004080; text-decoration: none; } +a:visited { font-weight: bold; color: #006699; text-decoration: none; } +a:link:hover { text-decoration: underline; } + +hr { + color:#cccccc; + background: #00007f; + height: 1px; +} + +blockquote { margin-left: 3em; } + +ul { list-style-type: disc; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; +} + +pre { + background-color: rgb(245, 245, 245); + border: 1px solid #C0C0C0; /* silver */ + padding: 10px; + margin: 10px 0 10px 0; + overflow: auto; + font-family: "Andale Mono", monospace; +} + +pre.example { + font-size: .85em; +} + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } + +#container { + margin-left: 1em; + margin-right: 1em; + background-color: #f0f0f0; +} + +#product { + text-align: center; + border-bottom: 1px solid #cccccc; + background-color: #ffffff; +} + +#product big { + font-size: 2em; +} + +#main { + background-color: #f0f0f0; + border-left: 2px solid #cccccc; +} + +#navigation { + float: left; + width: 14em; + vertical-align: top; + background-color: #f0f0f0; + overflow: visible; +} + +#navigation h2 { + background-color:#e7e7e7; + font-size:1.1em; + color:#000000; + text-align: left; + padding:0.2em; + border-top:1px solid #dddddd; + border-bottom:1px solid #dddddd; +} + +#navigation ul +{ + font-size:1em; + list-style-type: none; + margin: 1px 1px 10px 1px; +} + +#navigation li { + text-indent: -1em; + display: block; + margin: 3px 0px 0px 22px; +} + +#navigation li li a { + margin: 0px 3px 0px -1em; +} + +#content { + margin-left: 14em; + padding: 1em; + width: 700px; + border-left: 2px solid #cccccc; + border-right: 2px solid #cccccc; + background-color: #ffffff; +} + +#about { + clear: both; + padding: 5px; + border-top: 2px solid #cccccc; + background-color: #ffffff; +} + +@media print { + body { + font: 12pt "Times New Roman", "TimeNR", Times, serif; + } + a { font-weight: bold; color: #004080; text-decoration: underline; } + + #main { + background-color: #ffffff; + border-left: 0px; + } + + #container { + margin-left: 2%; + margin-right: 2%; + background-color: #ffffff; + } + + #content { + padding: 1em; + background-color: #ffffff; + } + + #navigation { + display: none; + } + pre.example { + font-family: "Andale Mono", monospace; + font-size: 10pt; + page-break-inside: avoid; + } +} + +table.module_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.module_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.module_list td.name { background-color: #f0f0f0; min-width: 200px; } +table.module_list td.summary { width: 100%; } + + +table.function_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.function_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.function_list td.name { background-color: #f0f0f0; min-width: 200px; } +table.function_list td.summary { width: 100%; } + +ul.nowrap { + overflow:auto; + white-space:nowrap; +} + +dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} +dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;} +dl.table h3, dl.function h3 {font-size: .95em;} + +/* stop sublists from having initial vertical space */ +ul ul { margin-top: 0px; } +ol ul { margin-top: 0px; } +ol ol { margin-top: 0px; } +ul ol { margin-top: 0px; } + +/* make the target distinct; helps when we're navigating to a function */ +a:target + * { + background-color: #FF9; +} + + +/* styles for prettification of source */ +pre .comment { color: #558817; } +pre .constant { color: #a8660d; } +pre .escape { color: #844631; } +pre .keyword { color: #aa5050; font-weight: bold; } +pre .library { color: #0e7c6b; } +pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; } +pre .string { color: #8080ff; } +pre .number { color: #f8660d; } +pre .operator { color: #2239a8; font-weight: bold; } +pre .preprocessor, pre .prepro { color: #a33243; } +pre .global { color: #800080; } +pre .user-keyword { color: #800080; } +pre .prompt { color: #558817; } +pre .url { color: #272fc2; text-decoration: underline; } + diff --git a/doc/modules/ExpGamingCore.Commands.html b/doc/modules/ExpGamingCore.Commands.html new file mode 100644 index 00000000..14672de7 --- /dev/null +++ b/doc/modules/ExpGamingCore.Commands.html @@ -0,0 +1,401 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Command

+

A full ranking system for factorio.

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + + + + + +
format_inputs (command)Returns the inputs of this command as a formated string
validate_args (event)Used to validate the arguments of a command, will understand strings with "" as a single param else spaces divede the params
get_commands (player)Used to return all the commands a player can use
add_command (name[, description='No Description'][, inputs=an infite string], callback)Used to define commands
+

Tables

+ + + + + +
validateCollection of funcations that can be used to validate inputs
+

Fields

+ + + + + + + + + +
errorUsed as an error constant for validation
dataIndex of all command data
+ +
+
+ + +

Functions

+ +
+
+ + format_inputs (command) +
+
+ Returns the inputs of this command as a formated string + + +

Parameters:

+
    +
  • command + string, table or event + the command to get the inputs of +
  • +
+ +

Returns:

+
    + + string + the formated string for the inputs +
+ + + +

Usage:

+
    +
    commands.format_inputs('interface') -- returns <code> (if you have ExpGamingCore.Server)
    +
+ +
+
+ + validate_args (event) +
+
+ Used to validate the arguments of a command, will understand strings with "" as a single param else spaces divede the params + + +

Parameters:

+
    +
  • event + table + this is the event created by add_command not on_console_command +
  • +
+ +

Returns:

+
    + + string + the error that happend while parsing the args +
+

Or

+
    + + table + the args for this command +
+

Or

+
    + + command.error +
+ + + +

Usage:

+
    +
    commands.validate_args(event) -- returns args table
    +
+ +
+
+ + get_commands (player) +
+
+ Used to return all the commands a player can use + + +

Parameters:

+
    +
  • player + index, name or player + the player to test as +
  • +
+ +

Returns:

+
    + + table + a table containg all the commands the player can use +
+ + + +

Usage:

+
    +
    get_commands(1) -- return table of command data for each command that the player can use
    +
+ +
+
+ + add_command (name[, description='No Description'][, inputs=an infite string], callback) +
+
+ Used to define commands + + +

Parameters:

+
    +
  • name + string + the name of the command +
  • +
  • description + string + the description of the command + (default 'No Description') +
  • +
  • inputs + table + a table of the inputs to be used, last index being true makes the last parameter open ended (longer than one word) + (default an infite string) +
  • +
  • callback + function + the function to call on the event +
  • +
+ + + + +

Usage:

+
    +
    --see examples in file
    +
+ +
+
+

Tables

+ +
+
+ + validate +
+
+ Collection of funcations that can be used to validate inputs + + +

Fields:

+
    +
  • __comment + replace _ with - the ldoc did not like me using - in the names +
  • +
  • string + basicly does nothing but a type filed is required +
  • +
  • string_inf + same as string but is infite in length, must be last arg +
  • +
  • string_len + same as string but can define a max lengh +
  • +
  • number + converts the input into a number +
  • +
  • number_int + conerts the input to a number and floors it +
  • +
  • number_range + allows a number in a range after it has been floored min < math.floor(X) <= max +
  • +
  • number_range + allows a number in a range after it has been floored min < math.floor(X) <= max +
  • +
  • player + converts the input into a valid player +
  • +
  • player_online + converts the input to a player if the player is online +
  • +
  • player_alive + converts the input to a player if the player is online and alive +
  • +
  • player_rank + -online converts the input to a player if the player is a lower rank than the user and online +
  • +
  • player_rank + -online converts the input to a player if the player is a lower rank than the user and online +
  • +
  • player_rank_alive + converts the input to a player if the player is a lower rank than the user and online and alive +
  • +
  • type + string + the type that the value should be +
  • +
  • value + the value that will be tested +
  • +
  • ... + any other data that can be passed to the function +
  • +
+ + + + +

Usage:

+
    +
    commands.validate[type](value,event,...)
    +
+ +
+
+

Fields

+ +
+
+ + error +
+
+ Used as an error constant for validation + + + + + + +

Usage:

+
    +
  • return commands.error, 'err message'
  • +
  • return commands.error('err message')
  • +
+ +
+
+ + data +
+
+ Index of all command data + + +
    +
  • key + string, table or event + the command that will be returned: string is the name, table is the command data, event is event from add_command +
  • +
+ + + + +

Usage:

+
    +
  • commands.command_name -- returns command data
  • +
  • commands.data -- returns all data
  • +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Gui.Center.html b/doc/modules/ExpGamingCore.Gui.Center.html new file mode 100644 index 00000000..b6b0f202 --- /dev/null +++ b/doc/modules/ExpGamingCore.Gui.Center.html @@ -0,0 +1,337 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Gui.Center

+

Adds a uniform preset for guis in the center of the screen which allow for different tabs to be opened

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_comment ()This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module
add (obj)Adds a new obj to the center gui
get_flow (player)Used to get the center frame of the player, used mainly in script
open (player, center)Used to open a center frame for a player
open_tab (player, center, tab)Used to open a center frame for a player
clear (player)Used to clear the center frame of the player, used mainly in script
center._center:add_tab (name, caption[, tooltip], callback)If deafult draw is used then you can add tabs to the gui with this function
+ +
+
+ + +

Functions

+ +
+
+ + _comment () +
+
+ This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module + + + + + + + +
+
+ + add (obj) +
+
+ Adds a new obj to the center gui + + +

Parameters:

+
    +
  • obj + contains the new object, needs name, fraw is opt and is function(root_frame) +
  • +
+ +

Returns:

+
    + + the object made, used to add tabs +
+ + + +

Usage:

+
    +
    Gui.center.add{name='foo',caption='Foo',tooltip='Testing',draw=function}
    +
+ +
+
+ + get_flow (player) +
+
+ Used to get the center frame of the player, used mainly in script + + +

Parameters:

+
    +
  • player + a player indifier to get the flow for +
  • +
+ +

Returns:

+
    + + table + the gui element flow +
+ + + +

Usage:

+
    +
    Gui.center.get_flow(player) -- returns gui emelemt
    +
+ +
+
+ + open (player, center) +
+
+ Used to open a center frame for a player + + +

Parameters:

+
    +
  • player + a player indifier to get the flow for +
  • +
  • center + string + the name of the center frame to open +
  • +
+ +

Returns:

+
    + + boolean + based on if it successed or not +
+ + + +

Usage:

+
    +
    Gui.center.open(player,'server-info') -- return true
    +
+ +
+
+ + open_tab (player, center, tab) +
+
+ Used to open a center frame for a player + + +

Parameters:

+
    +
  • player + a player indifier to get the flow for +
  • +
  • center + string + the name of the center frame to open +
  • +
  • tab + string + the name of the tab to open +
  • +
+ +

Returns:

+
    + + boolean + based on if it successed or not +
+ + + +

Usage:

+
    +
    Gui.center.open_tab(player,'readme','rules') -- return true
    +
+ +
+
+ + clear (player) +
+
+ Used to clear the center frame of the player, used mainly in script + + +

Parameters:

+
    +
  • player + a player indifier to get the flow for +
  • +
+ + + + +

Usage:

+
    +
    Gui.center.clear(player)
    +
+ +
+
+ + center._center:add_tab (name, caption[, tooltip], callback) +
+
+ If deafult draw is used then you can add tabs to the gui with this function + + +

Parameters:

+
    +
  • name + string + this is the name of the tab +
  • +
  • caption + string + this is the words that appear on the tab button +
  • +
  • tooltip + string + the tooltip that is on the button + (optional) +
  • +
  • callback + function + this is called when button is pressed with function(root_frame) +
  • +
+ +

Returns:

+
    + + self to allow chaining of _center:add_tab +
+ + + +

Usage:

+
    +
    _center:add_tab('foo','Foo','Just a tab',function)
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Gui.Inputs.html b/doc/modules/ExpGamingCore.Gui.Inputs.html new file mode 100644 index 00000000..b96c8532 --- /dev/null +++ b/doc/modules/ExpGamingCore.Gui.Inputs.html @@ -0,0 +1,498 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Gui.Inputs

+

Adds a clean way of making new inputs for a gui allowing for sliders and text inputs to be hanndleded with custom events

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_comment ()This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module
inputs._input:on_event (event, callback)Sets the input to trigger on an certain event
inputs._input:draw (root)Draw the input into the root element
add (obj)Add a new input, this is the same as doing frame.add{} but returns a diffrent object
add_elem_button (name, elem_type, tooltip, callback)Used to define a choose-elem-button callback only on elem_changed
add_checkbox (name, radio, display, default, callback_true, callback_false)Used to define a checkbox callback only on state_changed
reset_radio (elements)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.
add_text (name, box, text, callback)Used to define a text callback only on text_changed
add_slider (name, orientation, min, max, start_callback, callback)Used to define a slider callback only on value_changed
add_drop_down (name, items, index, callback)Used to define a drop down callback only on value_changed
+ +
+
+ + +

Functions

+ +
+
+ + _comment () +
+
+ This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module + + + + + + + +
+
+ + inputs._input:on_event (event, callback) +
+
+ Sets the input to trigger on an certain event + + +

Parameters:

+
    +
  • event + the event to raise callback on | can be number of the event | can be a key of inputs.events +
  • +
  • callback + function + the function you want to run on the event +
  • +
+ +

Returns:

+
    + + table + returns self so you can chain together +
+ + + +

Usage:

+
    +
    button:on_event(defines.events.on_gui_click,player_return)
    +
+ +
+
+ + inputs._input:draw (root) +
+
+ Draw the input into the root element + + +

Parameters:

+
    +
  • root + the element you want to add the input to +
  • +
+ +

Returns:

+
    + + returns the element that was added +
+ + + +

Usage:

+
    +
    button:draw(frame)
    +
+ +
+
+ + add (obj) +
+
+ Add a new input, this is the same as doing frame.add{} but returns a diffrent object + + +

Parameters:

+
    +
  • obj + table + the new element to add if caption is a sprite path then sprite is used +
  • +
+ +

Returns:

+
    + + table + the custom input object +
+ + + +

Usage:

+
    +
    Gui.inputs.add{type='button',name='test',caption='Test'}
    +
+ +
+
+ + add_elem_button (name, elem_type, tooltip, callback) +
+
+ Used to define a choose-elem-button callback only on elem_changed + + +

Parameters:

+
    +
  • name + string + the name of this button +
  • +
  • elem_type + string + the display for this button, either text or sprite path +
  • +
  • tooltip + string + the tooltip to show on the button +
  • +
  • callback + function + the callback to call on change function(player,element,elem) +
  • +
+ +

Returns:

+
    + + table + the button object that was made, to allow a custom error event if wanted +
+ + + +

Usage:

+
    +
    Gui.inputs.add_elem_button('test','Test','Just for testing',function)
    +
+ +
+
+ + add_checkbox (name, radio, display, default, callback_true, callback_false) +
+
+ Used to define a checkbox callback only on state_changed + + +

Parameters:

+
    +
  • name + string + the name of this button +
  • +
  • radio + boolean + if this is a radio button +
  • +
  • display + string + the display for this button, either text or sprite path +
  • +
  • default + function + the callback which choses the default check state +
  • +
  • callback_true + function + the callback to call when changed to true +
  • +
  • callback_false + function + the callback to call when changed to false +
  • +
+ +

Returns:

+
    + + table + the button object that was made, to allow a custom error event if wanted +
+ + + +

Usage:

+
    +
    Gui.inputs.add_checkbox('test',false,'Just for testing',function,function,funvtion)
    +
+ +
+
+ + reset_radio (elements) +
+
+ 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. + + +

Parameters:

+
    +
  • elements + can be a list of elements or a single element +
  • +
+ + + + +

Usage:

+
    +
    Gui.inputs.reset_radio{radio1,radio2,...}
    +
+ +
+
+ + add_text (name, box, text, callback) +
+
+ Used to define a text callback only on text_changed + + +

Parameters:

+
    +
  • name + string + the name of this button +
  • +
  • box + boolean + is it a text box rather than a text field +
  • +
  • text + string + the starting text +
  • +
  • callback + function + the callback to call on change function(player,text,element) +
  • +
+ +

Returns:

+
    + + table + the text object that was made, to allow a custom error event if wanted +
+ + + +

Usage:

+
    +
    Gui.inputs.add_text('test',false,'Just for testing',function)
    +
+ +
+
+ + add_slider (name, orientation, min, max, start_callback, callback) +
+
+ Used to define a slider callback only on value_changed + + +

Parameters:

+
    +
  • name + string + the name of this button +
  • +
  • orientation + string + direction of the slider +
  • +
  • min + number + the lowest number +
  • +
  • max + number + the highest number +
  • +
  • start_callback + function + either a number or a function to return a number +
  • +
  • callback + function + the function to be called on value_changed function(player,value,percent,element) +
  • +
+ +

Returns:

+
    + + table + the slider object that was made, to allow a custom error event if wanted +
+ + + +

Usage:

+
    +
    Gui.inputs.add_slider('test','horizontal',1,10,5,function)
    +
+ +
+
+ + add_drop_down (name, items, index, callback) +
+
+ Used to define a drop down callback only on value_changed + + +

Parameters:

+
    +
  • name + string + name of the drop down +
  • +
  • items + either a list or a function which returns a list +
  • +
  • index + either a number or a function which returns a number +
  • +
  • callback + function + the callback which is called when a new index is selected function(player,selected,items,element) +
  • +
+ +

Returns:

+
    + + table + the drop-down object that was made, to allow a custom error event if wanted +
+ + + +

Usage:

+
    +
    Gui.inputs.add_drop_down('test',{1,2,3},1,function)
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Gui.Left.html b/doc/modules/ExpGamingCore.Gui.Left.html new file mode 100644 index 00000000..b1fc3ddc --- /dev/null +++ b/doc/modules/ExpGamingCore.Gui.Left.html @@ -0,0 +1,240 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Gui.Left

+

Adds a organiser for left gui ellements which will automaticaly update there information and have open requirements

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + +
_comment ()This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module
add (obj)Used to add a left gui frame
update ([frame[, players]])This is used to update all the guis of connected players, good idea to use our thread system as it as nested for loops
open (left_name)Used to open the left gui of every player
close (left_name)Used to close the left gui of every player
+ +
+
+ + +

Functions

+ +
+
+ + _comment () +
+
+ This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module + + + + + + + +
+
+ + add (obj) +
+
+ Used to add a left gui frame + + +

Parameters:

+
    +
  • obj + this is what will be made, needs a name and a draw function(root_frame), open_on_join can be used to set the deaful state true/false, can_open is a test to block it from opening but is not needed +
  • +
+ +

Returns:

+
    + + the object that is made to... well idk but for the future +
+ + + +

Usage:

+
    +
    Gui.left.add{name='foo',caption='Foo',tooltip='just testing',open_on_join=true,can_open=function,draw=function}
    +
+ +
+
+ + update ([frame[, players]]) +
+
+ This is used to update all the guis of connected players, good idea to use our thread system as it as nested for loops + + +

Parameters:

+
    +
  • frame + string + this is the name of a frame if you only want to update one + (optional) +
  • +
  • players + the player to update for, if not given all players are updated, can be one player + (optional) +
  • +
+ + + + +

Usage:

+
    +
    Gui.left.update()
    +
+ +
+
+ + open (left_name) +
+
+ Used to open the left gui of every player + + +

Parameters:

+
    +
  • left_name + string + this is the gui that you want to open +
  • +
+ + + + +

Usage:

+
    +
    Gui.left.open('foo')
    +
+ +
+
+ + close (left_name) +
+
+ Used to close the left gui of every player + + +

Parameters:

+
    +
  • left_name + string + this is the gui that you want to close +
  • +
+ + + + +

Usage:

+
    +
    Gui.left.close('foo')
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Gui.Popup.html b/doc/modules/ExpGamingCore.Gui.Popup.html new file mode 100644 index 00000000..f1567b56 --- /dev/null +++ b/doc/modules/ExpGamingCore.Gui.Popup.html @@ -0,0 +1,185 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Gui.Popup

+

Adds a location for popups which can be dismissed by a player and created from other scripts

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + +
_comment ()This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module
add (obj)Used to add a popup gui style
open (style, data[, players=game.connected_players])Use to open a popup for these players
+ +
+
+ + +

Functions

+ +
+
+ + _comment () +
+
+ This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module + + + + + + + +
+
+ + add (obj) +
+
+ Used to add a popup gui style + + +

Parameters:

+
    +
  • obj + this is what will be made, needs a name and a draw function(root_frame,data) +
  • +
+ +

Returns:

+
    + + the object that is made to... well idk but for the future +
+ + + +

Usage:

+
    +
    Gui.left.add{name='foo',caption='Foo',draw=function}
    +
+ +
+
+ + open (style, data[, players=game.connected_players]) +
+
+ Use to open a popup for these players + + +

Parameters:

+
    +
  • style + string + this is the name you gave to the popup when added +
  • +
  • data + this is the data that is sent to the draw function +
  • +
  • players + table + the players to open the popup for + (default game.connected_players) +
  • +
+ + + + +

Usage:

+
    +
    Gui.popup.open('ban',nil,{player=1,reason='foo'})
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Gui.Test.html b/doc/modules/ExpGamingCore.Gui.Test.html new file mode 100644 index 00000000..c5fc942d --- /dev/null +++ b/doc/modules/ExpGamingCore.Gui.Test.html @@ -0,0 +1,144 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Gui.Test

+

Used to test all gui elements and parts can be used in game via Gui.test()

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + +
_comment ()This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module
Gui.test ([player=game.player])The funcation that is called when calling Gui.test
+ +
+
+ + +

Functions

+ +
+
+ + _comment () +
+
+ This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module + + + + + + + +
+
+ + Gui.test ([player=game.player]) +
+
+ The funcation that is called when calling Gui.test + + +

Parameters:

+
    +
  • player + a pointer to a player to draw the test gui for + (default game.player) +
  • +
+ + + + +

Usage:

+
    +
    Gui.test() -- draws test gui
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Gui.Toolbar.html b/doc/modules/ExpGamingCore.Gui.Toolbar.html new file mode 100644 index 00000000..7abec4aa --- /dev/null +++ b/doc/modules/ExpGamingCore.Gui.Toolbar.html @@ -0,0 +1,190 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Gui.Toolbar

+

Adds a toolbar to the top left of the screen

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + +
_comment ()This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module
add (name, caption, tooltip, callback)Add a button to the toolbar, ranks need to be allowed to use these buttons if ranks is preset
draw (player)Draws the toolbar for a certain player
+ +
+
+ + +

Functions

+ +
+
+ + _comment () +
+
+ This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module + + + + + + + +
+
+ + add (name, caption, tooltip, callback) +
+
+ Add a button to the toolbar, ranks need to be allowed to use these buttons if ranks is preset + + +

Parameters:

+
    +
  • name + string + the name of the button +
  • +
  • caption + string + can be a sprite path or text to show +
  • +
  • tooltip + string + the help to show for the button +
  • +
  • callback + function + the function which is called on_click +
  • +
+ +

Returns:

+
    + + table + the button object that was made +
+ + + +

Usage:

+
    +
    toolbar.add('foo','Foo','Test',function() game.print('test') end)
    +
+ +
+
+ + draw (player) +
+
+ Draws the toolbar for a certain player + + +

Parameters:

+
    +
  • player + the player to draw the tool bar of +
  • +
+ + + + +

Usage:

+
    +
    toolbar.draw(1)
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Gui.html b/doc/modules/ExpGamingCore.Gui.html new file mode 100644 index 00000000..b5fea915 --- /dev/null +++ b/doc/modules/ExpGamingCore.Gui.html @@ -0,0 +1,366 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Gui

+

Adds a objective version to custom guis.

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + +
bar (frame[, width=10])Add a white bar to any gui frame
set_dropdown_index (dropdown, _item)Used to set the index of a drop down to a certian item
cam_link (data)Adds a camera that updates every tick (or less depeading on how many are opening) it will move to follow an entity
+

Tables

+ + + + + + + + + +
eventsStores all the on_player_joined_game event handlers for the guis
ParametersForCamLinkPrams for Gui.cam_link
+

Fields

+ + + + + +
dataUsed to set and get data about different guis
+

modules.expgamingcore.gui.src.server Functions

+ + + + + + + + + +
_comment ()This file will be loaded when ExpGamingCore.Command is present
__comment ()Adds a server thread that allows the camera follows to be toggled off and on
+ +
+
+ + +

Functions

+ +
+
+ + bar (frame[, width=10]) +
+
+ Add a white bar to any gui frame + + +

Parameters:

+
    +
  • frame + the frame to draw the line to +
  • +
  • width + the width of the bar + (default 10) +
  • +
+ +

Returns:

+
    + + the line that was made type is progressbar +
+ + + +

Usage:

+
    +
    Gui.bar(frame,100)
    +
+ +
+
+ + set_dropdown_index (dropdown, _item) +
+
+ Used to set the index of a drop down to a certian item + + +

Parameters:

+
    +
  • dropdown + the dropdown that is to be effected +
  • +
  • _item + this is the item to look for +
  • +
+ +

Returns:

+
    + + returns the dropdown if it was successful +
+ + + +

Usage:

+
    +
    Gui.set_dropdown_index(dropdown,player.name) -- will select the index with the players name as the value
    +
+ +
+
+ + cam_link (data) +
+
+ Adds a camera that updates every tick (or less depeading on how many are opening) it will move to follow an entity + + +

Parameters:

+
    +
  • data + table + contains all other params given below +
  • +
+ +

Returns:

+
    + + the camera that the function used be it made or given as a param +
+ + + +

Usage:

+
    +
  • Gui.cam_link{entity=game.player.character,frame=frame,width=50,hight=50,zoom=1}
  • +
  • Gui.cam_link{entity=game.player.character,cam=frame.camera,surface=game.surfaces['testing']}
  • +
+ +
+
+

Tables

+ +
+
+ + events +
+
+ Stores all the on_player_joined_game event handlers for the guis + + + + + + + +
+
+ + ParametersForCamLink +
+
+ Prams for Gui.cam_link + + +

Fields:

+
    +
  • entity + this is the entity that the camera will follow +
  • +
  • cam + a camera that you already have in the gui +
  • +
  • frame + the frame to add the camera to, no effect if cam param is given +
  • +
  • zoom + the zoom to give the new camera +
  • +
  • width + the width to give the new camera +
  • +
  • height + the height to give the new camera +
  • +
  • surface + this will over ride the surface that the camera follows on, allowing for a 'ghost surface' while keeping same position +
  • +
  • respawn_open + if set to true then the camera will auto re link to the player after a respawn +
  • +
+ + + + + +
+
+

Fields

+ +
+
+ + data +
+
+ Used to set and get data about different guis + + +
    +
  • location + string + the location to get/set the data, center left etc... +
  • +
  • key + string + the name of the gui to set the value of + (optional) +
  • +
  • value + the data that will be set can be any value but table advised + (optional) +
  • +
+ + + + +

Usage:

+
    +
  • Gui.data[location] -- returns the gui data for that gui location ex center
  • +
  • Gui.data(location,gui_name,gui_data) -- adds gui data for a gui at a location
  • +
+ +
+
+

modules.expgamingcore.gui.src.server Functions

+ +
+
+ + _comment () +
+
+ This file will be loaded when ExpGamingCore.Command is present + + + + + + + +
+
+ + __comment () +
+
+ Adds a server thread that allows the camera follows to be toggled off and on + + + + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Ranking.html b/doc/modules/ExpGamingCore.Ranking.html new file mode 100644 index 00000000..b63a6d37 --- /dev/null +++ b/doc/modules/ExpGamingCore.Ranking.html @@ -0,0 +1,883 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Role

+

A full ranking system for factorio.

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
output_ranks ([player=server])Outputs as a string all the ranks and the loaded order
_base_preset (ranks)Used to set the prset ranks that will be given to players
get_rank (mixed)Returns a rank object given a player or rank name
get_group (mixed)Returns the group object used to sort ranks given group name or rank
print (rank_base, rtn[, colour=defines.color.white[, below=false]])Prints to all rank of greater/lower power of the rank given
give_rank (player[, rank=default[, by_player='server'[, tick=game.tick]]])Gives a user a rank
revert (player[, by_player=nil])Revert the last change to a players rank
find_preset (player[, tick=nil])Given that the player has a rank in the preset table it is given; also will attempt to promote players if a time requirement is met
+

Tables

+ + + + + + + + + + + + + + + + + +
globalGlobal Table
ranksContains the location of all the ranks, readonly during runtime
ranksContains the location of all the rank groups, readonly during runtime
metaContains some meta data about the ranks
+

Events

+ + + + + +
on_rank_changeCalled when there is a rank change for a user
+

Class Rank

+ + + + + + + + + + + + + + + + + +
Ranking._rank:allowed (action)Is this rank allowed to open this gui or use this command etc.
Ranking._rank:get_players ([online=false])Get all the players in this rank
Ranking._rank:print (rtn[, colour=defines.color.white[, show_default=false]])Print a message to all players of this rank
Ranking._rank:edit (key, value)Allows for a clean way to edit rank objects
+

Class Group

+ + + + + + + + + + + + + +
Ranking._group:create (obj)Creates a new group
Ranking._group:add_rank (obj)Creats a new rank with this group as its group
Ranking._group:edit (key, value)Allows for a clean way to edit rank group objects
+

modules.expgamingcore.ranking.src.server Functions

+ + + + + + + + + +
_comment ()This file will be loaded when ExpGamingCore.Server is present
Ranking._rank:print (rtn[, colour=defines.color.white[, show_default=false]])Print a message to all players of this rank
+ +
+
+ + +

Functions

+ +
+
+ + output_ranks ([player=server]) +
+
+ Outputs as a string all the ranks and the loaded order + + +

Parameters:

+
    +
  • player + player_name, player_index or LuaPlayer + the player that the info will be printed to, nil will print to server + (default server) +
  • +
+ + + + +

Usage:

+
    +
    Ranking.output_ranks(player) -- prints to player
    +
+ +
+
+ + _base_preset (ranks) +
+
+ Used to set the prset ranks that will be given to players + + +

Parameters:

+
    +
  • ranks + table + table of player names with the player name as the key and rank name as the value +
  • +
+ + + + +

Usage:

+
    +
    Ranking._base_preset{name=rank_name,nameTwo=rank_name_two} -- sets player name to have rank rank_name on join
    +
+ +
+
+ + get_rank (mixed) +
+
+ Returns a rank object given a player or rank name + + +

Parameters:

+
    +
  • mixed + player, player_index, player_name, rank_name, Ranking._rank, 'server' or 'root' + what rank to get +
  • +
+ +

Returns:

+
    + + table + the rank that is linked to mixed +
+

Or

+
    + + nil + there was no rank found +
+ + + +

Usage:

+
    +
  • Ranking.get_rank(game.player) -- returns player's rank
  • +
  • Ranking.get_rank('admin') -- returns rank by the name of admin
  • +
+ +
+
+ + get_group (mixed) +
+
+ Returns the group object used to sort ranks given group name or rank + + +

Parameters:

+
    +
  • mixed + player, player_index, player_name, rank_name, rank, 'server', 'root', group_name or group + what group to get +
  • +
+ +

Returns:

+
    + + table + the group that is linked to mixed +
+

Or

+
    + + nil + there was no rank group found +
+ + +

See also:

+ + +

Usage:

+
    +
  • Ranking.get_group(game.player) -- returns player's rank group
  • +
  • Ranking.get_group('root') -- returns group by name of root
  • +
+ +
+
+ + print (rank_base, rtn[, colour=defines.color.white[, below=false]]) +
+
+ Prints to all rank of greater/lower power of the rank given + + +

Parameters:

+
    +
  • rank_base + Ranking._rank or pointerToRank + the rank that acts as the cut off point (rank is always included) +
  • +
  • rtn + what do you want to return to the players +
  • +
  • colour + defines.color + the colour that will be used to print + (default defines.color.white) +
  • +
  • below + boolean + if true print to children rather than parents + (default false) +
  • +
+ + + + +

Usage:

+
    +
    Ranking.print('admin','We got a grifer')
    +
+ +
+
+ + give_rank (player[, rank=default[, by_player='server'[, tick=game.tick]]]) +
+
+ Gives a user a rank + + +

Parameters:

+
    +
  • player + LuaPlayer or pointerToPlayer + the player to give the rank to +
  • +
  • rank + Ranking._rank or pointerToRank + the rank to give to the player + (default default) +
  • +
  • by_player + LuaPlayer or pointerToPlayer + the player who is giving the rank + (default 'server') +
  • +
  • tick + number + the tick that the rank is being given on, used as pass though + (default game.tick) +
  • +
+ + + + +

Usage:

+
    +
    Ranking.give_rank(1,'admin')
    +
+ +
+
+ + revert (player[, by_player=nil]) +
+
+ Revert the last change to a players rank + + +

Parameters:

+
    +
  • player + LuaPlayer or pointerToPlayer + the player to revert the rank of +
  • +
  • by_player + the player who is doing the revert + (default nil) +
  • +
+ + + + +

Usage:

+
    +
    Ranking.revert(1) -- reverts the rank of player with index 1
    +
+ +
+
+ + find_preset (player[, tick=nil]) +
+
+ Given that the player has a rank in the preset table it is given; also will attempt to promote players if a time requirement is met + + +

Parameters:

+
    +
  • player + LuaPlayer or pointerToPlayer + the player to test for an auto rank +
  • +
  • tick + number + the tick it happens on + (default nil) +
  • +
+ + + + +

Usage:

+
    +
    Ranking.find_preset(1) -- attemps to find the preset for player with index 1
    +
+ +
+
+

Tables

+ +
+
+ + global +
+
+ Global Table + + +

Fields:

+
    +
  • old + contains the previous rank a use had before a rank change +
  • +
  • preset + contains the preset ranks that users will recive apon joining +
  • +
  • last_change + contains the name of the player who last had there rank chagned +
  • +
+ + + + + +
+
+ + ranks +
+
+ Contains the location of all the ranks, readonly during runtime + + + + + + + +
+
+ + ranks +
+
+ Contains the location of all the rank groups, readonly during runtime + + + + + + + +
+
+ + meta +
+
+ Contains some meta data about the ranks + + +

Fields:

+
    +
  • default + this is the name of the default rank +
  • +
  • root + this is the name of the root rank +
  • +
  • time_ranks + a list of all ranks which have a time requirement +
  • +
  • time_highest + the power of the highest rank that has a time requirement +
  • +
  • time_lowest + the lowest amount of time required for a time rank +
  • +
+ + + + + +
+
+

Events

+ +
+
+ + on_rank_change +
+
+ Called when there is a rank change for a user + + +

field:

+
    +
  • name + the rank id +
  • +
  • tick + the tick which the event was raised on +
  • +
  • player_index + the player whos rank was changed +
  • +
  • by_player_index + the player who changed the rank, 0 means server +
  • +
  • new_rank + the name of the rank that was given +
  • +
  • old_rank + the name of the rank the player had +
  • +
+ + + + + +
+
+

Class Rank

+ +
+ The class for the ranks +
+
+
+ + Ranking._rank:allowed (action) +
+
+ Is this rank allowed to open this gui or use this command etc. + + +

Parameters:

+
    +
  • action + teh + to test for +
  • +
+ +

Returns:

+
    + + boolean + is it allowed +
+ + + +

Usage:

+
    +
    rank:allowed('interface') -- does the rank have permision for 'interface'
    +
+ +
+
+ + Ranking._rank:get_players ([online=false]) +
+
+ Get all the players in this rank + + +

Parameters:

+
    +
  • online + boolean + get only online players + (default false) +
  • +
+ +

Returns:

+
    + + table + a table of all players in this rank +
+ + + +

Usage:

+
    +
    rank:get_players()
    +
+ +
+
+ + Ranking._rank:print (rtn[, colour=defines.color.white[, show_default=false]]) +
+
+ Print a message to all players of this rank + + +

Parameters:

+
    +
  • rtn + any value you want to return +
  • +
  • colour + define.color + the colour that will be used to print + (default defines.color.white) +
  • +
  • show_default + boolean + weather to use the default rank name for the print, used as a pass though + (default false) +
  • +
+ + + + +

Usage:

+
    +
    rank:print('foo') -- prints to all members of this rank
    +
+ +
+
+ + Ranking._rank:edit (key, value) +
+
+ Allows for a clean way to edit rank objects + + +

Parameters:

+
    +
  • key + string + the key to edit, often allow or disallow +
  • +
  • value + the new value to be set +
  • +
+ + + + +

Usage:

+
    +
    rank:edit('allow',{'interface'}) -- allows this rank to use 'interface'
    +
+ +
+
+

Class Group

+ +
+ The class for the rank groups, the way to allow modules to idex a group that is always present, ranks will always look to there group as a parent +
+
+
+ + Ranking._group:create (obj) +
+
+ Creates a new group + + +

Parameters:

+
    +
  • obj + table + the fields for this object +
  • +
+ +

Returns:

+
    + + Ranking._group + returns the object to allow chaining +
+ + + +

Usage:

+
    +
    Ranking._group:create{name='root'} -- returns group with name root
    +
+ +
+
+ + Ranking._group:add_rank (obj) +
+
+ Creats a new rank with this group as its group + + +

Parameters:

+
    +
  • obj + table + the fields for this object +
  • +
+ +

Returns:

+
    + + Ranking._group + returns the object to allow chaining +
+ + + +

Usage:

+
    +
    group:add_rank{name='root'} -- returns self
    +
+ +
+
+ + Ranking._group:edit (key, value) +
+
+ Allows for a clean way to edit rank group objects + + +

Parameters:

+
    +
  • key + string + the key to edit, often allow or disallow +
  • +
  • value + the new value to be set +
  • +
+ + + + +

Usage:

+
    +
    group:edit('allow',{'interface'}) -- allows this rank to use 'interface'
    +
+ +
+
+

modules.expgamingcore.ranking.src.server Functions

+ +
+
+ + _comment () +
+
+ This file will be loaded when ExpGamingCore.Server is present + + + + + + + +
+
+ + Ranking._rank:print (rtn[, colour=defines.color.white[, show_default=false]]) +
+
+ Print a message to all players of this rank + + +

Parameters:

+
    +
  • rtn + any value you want to return +
  • +
  • colour + define.color + the colour that will be used to print + (default defines.color.white) +
  • +
  • show_default + boolean + weather to use the default rank name for the print, used as a pass though + (default false) +
  • +
+ + + + +

Usage:

+
    +
    rank:print('foo') -- prints to all members of this rank
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Server.html b/doc/modules/ExpGamingCore.Server.html new file mode 100644 index 00000000..5bd0827d --- /dev/null +++ b/doc/modules/ExpGamingCore.Server.html @@ -0,0 +1,848 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Server

+

Adds a thread system and event listening and a admin bypass (recommend to disable /c and use optional /interface)

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
new_thread (obj)Generates a new thread object
get_thread (mixed)Used to get a thread via uuid or name (if one is assied)
queue_thread (thread_to_queue)Adds a thread into the resolve queue, can be used to lower lag
close_all_threads (with_force)Closes all active threads, can use force if it causes errors
run_tick_threads ()Runs all the theads which have opened with an on_tick event
check_timeouts ()Checks the timeout on all active timeout threads
_thread_debuger (player, event[, state=toggle])Used to print event info to a player
interface (callback[, use_thread[, env[, ...]]])Acts as a bypass for running functions, can accept a string
+

Tables

+ + + + + +
globalGlobal Table
+

Fields

+ + + + + + + + + +
uuidUsed to generate a new uuid for the thread system
threadsRedirect to the thread index
+

Class Thread

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Server._thread:create ([obj={}])Returns a new thread object
Server._thread:queue ()Opens and queses a thread
Server._thread:valid ([skip_location_check=false])Test if the thread has all requied parts
Server._thread:open ()Opens the thread; indexs this thread in the global index
Server._thread:close ()Inverse of thread:open() - Removes all indexs to this thread, most cases this will cause it to become inassible
Server._thread:resolve ([...])Trigger the on_resolve function and closes the thread - error and success called based on result of pcall (useful for async)
Server._thread:check_timeout ()Checks the timeout on a thread - if timed out then it calles on_timeout and closes
Server._thread:error (err)Used to check and raise the error handler of the thread, if not present it raises an error
Server._thread:on_event (event, callback)Set function to run then an event is triggered, none of them are 'needed' but you are advised to have atleast one
+

modules.expgamingcore.server.src.commands Functions

+ + + + + + + + + +
_comment ()This file will be loaded when ExpGamingCore.Command is present
interfaceRuns the given input from the script
+ +
+
+ + +

Functions

+ +
+
+ + new_thread (obj) +
+
+ Generates a new thread object + + +

Parameters:

+
    +
  • obj + table + the atributes to give to the thread +
  • +
+ +

Returns:

+
    + + Server._thread + the new thread created +
+ + + +

Usage:

+
    +
    Server.new_thread{name='foo',data={}}
    +
+ +
+
+ + get_thread (mixed) +
+
+ Used to get a thread via uuid or name (if one is assied) + + +

Parameters:

+
    +
  • mixed + either a uuid or the name given to a thread +
  • +
+ +

Returns:

+
    + + Server._thread + the thread by that name or uuid +
+

Or

+
    + + boolean + if false is returned then no thread existes +
+ + + +

Usage:

+
    +
    Server.get_thread('decon') -- return thread
    +
+ +
+
+ + queue_thread (thread_to_queue) +
+
+ Adds a thread into the resolve queue, can be used to lower lag + + +

Parameters:

+
    +
  • thread_to_queue + Server._thread + the thread to be added to the queue, must be open and have a on_resolve function +
  • +
+ +

Returns:

+
    + + boolean + was it added successfuly +
+ + + +

Usage:

+
    +
    Server.queue_thread(thread) -- return true/false
    +
+ +
+
+ + close_all_threads (with_force) +
+
+ Closes all active threads, can use force if it causes errors + + +

Parameters:

+
    +
  • with_force + bolean + use force when closing +
  • +
+ + + + +

Usage:

+
    +
  • Server.close_all_threads() -- asks all threads to close
  • +
  • Server.close_all_threads(true) -- forcefuly close all threads
  • +
+ +
+
+ + run_tick_threads () +
+
+ Runs all the theads which have opened with an on_tick event + + + + + + +

Usage:

+
    +
    Server.run_tick_threads()
    +
+ +
+
+ + check_timeouts () +
+
+ Checks the timeout on all active timeout threads + + + + + + +

Usage:

+
    +
    Server.check_timeouts()
    +
+ +
+
+ + _thread_debuger (player, event[, state=toggle]) +
+
+ Used to print event info to a player + + +

Parameters:

+
    +
  • player + name, index or LuaPlayer + the player that the info will be returned to +
  • +
  • event + name or index + the event that info will be returned fo +
  • +
  • state + boolean + will info be returned, nil to toggle current state + (default toggle) +
  • +
+ + + + +

Usage:

+
    +
    Server._thread_debuger('Cooldude2606','on_player_died',true) -- will output event info to 'Cooldude2606' for 'on_player_died'
    +
+ +
+
+ + interface (callback[, use_thread[, env[, ...]]]) +
+
+ Acts as a bypass for running functions, can accept a string + + +

Parameters:

+
    +
  • callback + string or function + function to be ran +
  • +
  • use_thread + Server._thread or true + run the command on a premade thread or let it make its own + (optional) +
  • +
  • env + table + run the env to run the command in must have _env key as true to be + (optional) +
  • +
  • ... + any args you want to pass to the function + (optional) +
  • +
+ +

Returns:

+
    +
  1. + boolean + if no thread then it will return a true for the success
  2. +
  3. + if no thread then it will return the value(s) returned by the callback
  4. +
+

Or

+
    +
  1. + boolean + if no thread then it will return a false for the success
  2. +
  3. + string + if no thread then it will return a an err value
  4. +
+ + + +

Usage:

+
    +
  • Server.interface('local x = 1+1 print(x) return x') -- return 2
  • +
  • Server.interface('local x = 1+1 print(x)',true) -- will creat a thread to run as root (this is the bypass)
  • +
+ +
+
+

Tables

+ +
+
+ + global +
+
+ Global Table + + +

Fields:

+
    +
  • all + a list of every thread (indexed by uuid) +
  • +
  • queue + an index for threads which will be resolved (contains uuids) +
  • +
  • tick + an index for threads which will run every tick (contains uuids) +
  • +
  • timeout + an index for threads which will timeout (contains uuids) +
  • +
  • events + an index of threads based on event ids (contains uuids) +
  • +
  • paused + an index of pasued threads (contains uuids) +
  • +
  • named + a name index for thread uuids +
  • +
  • print_to + contains players that event details will be printed to +
  • +
  • uuid + contains the random number generator for the uuid system +
  • +
+ + + + + +
+
+

Fields

+ +
+
+ + uuid +
+
+ Used to generate a new uuid for the thread system + + + + + + +

Usage:

+
    +
    local uuid = tostring(Server.uuid) -- calling tostring locks the value
    +
+ +
+
+ + threads +
+
+ Redirect to the thread index + + + + + + +

Usage:

+
    +
  • Server.threads -- return #global.all
  • +
  • Server.threads -- return global.all
  • +
+ +
+
+

Class Thread

+ +
+ The class for the server threads, allows abbilty to run async function +
+
+
+ + Server._thread:create ([obj={}]) +
+
+ Returns a new thread object + + +

Parameters:

+
    +
  • obj + table + all values are opt {timeout=int,name=str,data=any} + (default {}) +
  • +
+ +

Returns:

+
    + + Server._thread + the new thread object +
+ + + +

Usage:

+
    +
    new_thread = thread:create()
    +
+ +
+
+ + Server._thread:queue () +
+
+ Opens and queses a thread + + + +

Returns:

+
    + + boolean + was the thread queued successfuly +
+ + +

See also:

+ + +

Usage:

+
    +
    Server._thread:queue() -- returns true/false
    +
+ +
+
+ + Server._thread:valid ([skip_location_check=false]) +
+
+ Test if the thread has all requied parts + + +

Parameters:

+
    +
  • skip_location_check + bolean + true to skip the location checking + (default false) +
  • +
+ +

Returns:

+
    + + boolean + is the thread valid +
+ + + +

Usage:

+
    +
    if thread:valid() then end -- basic test for valid
    +
+ +
+
+ + Server._thread:open () +
+
+ Opens the thread; indexs this thread in the global index + + + +

Returns:

+
    + + bolean + if the thread was opened successfuly +
+ + + +

Usage:

+
    +
    thread:open() -- return true
    +
+ +
+
+ + Server._thread:close () +
+
+ Inverse of thread:open() - Removes all indexs to this thread, most cases this will cause it to become inassible + + + +

Returns:

+
    + + boolean + if the thread had a on_close function +
+ + + +

Usage:

+
    +
    thread:close() -- return true
    +
+ +
+
+ + Server._thread:resolve ([...]) +
+
+ Trigger the on_resolve function and closes the thread - error and success called based on result of pcall (useful for async) + + +

Parameters:

+
    +
  • ... + any arguments you want to pass to the resolve function + (optional) +
  • +
+ +

Returns:

+
    + + bolean + true if the thread called on_success or on_error +
+ + + +

Usage:

+
    +
    thread:resolve(x,y,z) -- return true
    +
+ +
+
+ + Server._thread:check_timeout () +
+
+ Checks the timeout on a thread - if timed out then it calles on_timeout and closes + + + +

Returns:

+
    + + bolean + if the thread timed out +
+ + + +

Usage:

+
    +
    thread:check_timeout() -- return true
    +
+ +
+
+ + Server._thread:error (err) +
+
+ Used to check and raise the error handler of the thread, if not present it raises an error + + +

Parameters:

+
    +
  • err + string + the err to be rasied +
  • +
+ +

Returns:

+
    + + boolean + did the thread have an error handler +
+ + + +

Usage:

+
    +
    thread:error(err) -- return true
    +
+ +
+
+ + Server._thread:on_event (event, callback) +
+
+ Set function to run then an event is triggered, none of them are 'needed' but you are advised to have atleast one + + +

Parameters:

+
    +
  • event + string or index + the name of the event that the function should be called on +
  • +
  • callback + function + the function which is called by the event trigger +
  • +
+ +

Returns:

+
    + + table + returns self so that they can be chained together +
+ + + +

Usage:

+
    +
  • thread:on_event('close',function) -- if event is not one below then a game event is used
  • +
  • thread_only_events = ['close','timeout','tick','resolve','success','error']
  • +
+ +
+
+

modules.expgamingcore.server.src.commands Functions

+ +
+
+ + _comment () +
+
+ This file will be loaded when ExpGamingCore.Command is present + + + + + + + +
+
+ + interface +
+
+ Runs the given input from the script + + +

param:

+
    +
  • code + The code that will be ran +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingCore.Sync.html b/doc/modules/ExpGamingCore.Sync.html new file mode 100644 index 00000000..291dd92b --- /dev/null +++ b/doc/modules/ExpGamingCore.Sync.html @@ -0,0 +1,820 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingCore.Sync

+

Allows syncing with an outside server and info panle.

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
tick_format (tick)Used to standidise the tick format for any sync info
print (player_message, player_name[, player_tag[, player_colour[, prefix]]])Prints to chat as if it were a player
emit_embedded (args)Logs an embed to the json.data we use a js script to add things we cant here
count_admins ()Used to get the number of admins currently online
count_afk ([time=7200])Used to get the number of afk players defined by 2 min by default
count_ranks ()Used to get the number of players in each rank and currently online; if ExpGamingCore/Ranking is present then it will give more than admin and user
count_players (online)Used to get a list of every player name with the option to limit to only online players
count_player_times ()Used to get a list of every player name with the amount of time they have played for
update ()Called to update values inside of the info
add_update (key, callback)Adds a callback to be called when the info is updated
emit_data ()Outputs the curent server info into a file
+

Tables

+ + + + + + + + + + + + + +
globalGlobal Table
global.playersPlayer sub-table
EmitEmbededParamatersOutline of the paramaters accepted by Sync.emit_embedded
+

Fields

+ + + + + + + + + +
infoused to get the global list that has been defined, also used to set that list
timeUsed to return and set the current IRL time; not very good need a better way to do this
+

modules.expgamingcore.sync.src.gui Functions

+ + + + + + + + + + + + + +
_comment ()This file will be loaded when ExpGamingCore.Gui is present
add_to_gui (element)Adds a emeltent to the sever info gui
server-infoCreates a center gui that will appear on join
+

modules.expgamingcore.sync.src.ranking Functions

+ + + + + + + + + + + + + +
_comment ()This file will be loaded when ExpGamingCore.Role is present
set_ranks (...)Used as a redirect to Ranking._base_preset that will set the rank given to a player apon joining
count_ranks ()Used to get the number of players in each rank and currently online
+ +
+
+ + +

Functions

+ +
+
+ + tick_format (tick) +
+
+ Used to standidise the tick format for any sync info + + +

Parameters:

+
    +
  • tick + +
  • +
+ +

Returns:

+
    + + {number,string} + table containg both the raw number and clean version of a time +
+ + + +

Usage:

+
    +
    Sync.tick_format(60) -- return {60,'1.00M'}
    +
+ +
+
+ + print (player_message, player_name[, player_tag[, player_colour[, prefix]]]) +
+
+ Prints to chat as if it were a player + + +

Parameters:

+
    +
  • player_message + string + the message to be printed in chat +
  • +
  • player_name + string + the name of the player sending the message +
  • +
  • player_tag + string + the tag apllied to the player's name + (optional) +
  • +
  • player_colour + string + the colour of the message, either hex or named colour + (optional) +
  • +
  • prefix + string + add a prefix before the chat eg [IRC] + (optional) +
  • +
+ + + + +

Usage:

+
    +
    Sync.print('Test','Cooldude2606')
    +
+ +
+
+ + emit_embedded (args) +
+
+ Logs an embed to the json.data we use a js script to add things we cant here + + +

Parameters:

+
    +
  • args + table + a table which contains everything that the embedded will use +
  • +
+ + + +

See also:

+ + +

Usage:

+
    +
    Sync.emit_embedded{title='BAN',color='0x0',description='A player was banned' ... }
    +
+ +
+
+ + count_admins () +
+
+ Used to get the number of admins currently online + + + +

Returns:

+
    + + number + the number of admins online +
+ + + +

Usage:

+
    +
    Sync.count_admins() -- returns number
    +
+ +
+
+ + count_afk ([time=7200]) +
+
+ Used to get the number of afk players defined by 2 min by default + + +

Parameters:

+
    +
  • time + int + in ticks that a player is called afk + (default 7200) +
  • +
+ +

Returns:

+
    + + number + the number of afk players +
+ + + +

Usage:

+
    +
    Sync.count_afk()
    +
+ +
+
+ + count_ranks () +
+
+ Used to get the number of players in each rank and currently online; if ExpGamingCore/Ranking is present then it will give more than admin and user + + + +

Returns:

+
    + + table + contains the ranks and the players in that rank +
+ + + +

Usage:

+
    +
    Sync.count_ranks()
    +
+ +
+
+ + count_players (online) +
+
+ Used to get a list of every player name with the option to limit to only online players + + +

Parameters:

+
    +
  • online + boolean + true will get only the online players +
  • +
+ +

Returns:

+
    + + table + table of player names +
+ + + +

Usage:

+
    +
    Sync.count_players()
    +
+ +
+
+ + count_player_times () +
+
+ Used to get a list of every player name with the amount of time they have played for + + + +

Returns:

+
    + + table + table indexed by player name, each value contains the raw tick and then the clean string +
+ + + +

Usage:

+
    +
    Sync.count_player_times()
    +
+ +
+
+ + update () +
+
+ Called to update values inside of the info + + + +

Returns:

+
    + + all of the new info +
+ + + +

Usage:

+
    +
    Sync.update()
    +
+ +
+
+ + add_update (key, callback) +
+
+ Adds a callback to be called when the info is updated + + +

Parameters:

+
    +
  • key + string + the key that the value will be stored in +
  • +
  • callback + function + the function which will return this value +
  • +
+ + + + +

Usage:

+
    +
    Sync.add_update('players',function() return #game.players end)
    +
+ +
+
+ + emit_data () +
+
+ Outputs the curent server info into a file + + + + + + +

Usage:

+
    +
    Sync.emit_data()
    +
+ +
+
+

Tables

+ +
+
+ + global +
+
+ Global Table + + +

Fields:

+
    +
  • server_name + the server name +
  • +
  • server_description + a short description of the server +
  • +
  • reset_time + the reset time of the server +
  • +
  • time + the last knowen irl time +
  • +
  • time_set + the last in game time that the time was set +
  • +
  • last_update + the last time that this info was updated +
  • +
  • time_period + how often this infomation is updated +
  • +
  • players + a list of different player related states +
  • +
  • ranks + a list of player ranks +
  • +
  • rockets + the number of rockets launched +
  • +
  • mods + the mods which are loaded +
  • +
+ + + + + +
+
+ + global.players +
+
+ Player sub-table + + +

Fields:

+
    +
  • online + list of all players online +
  • +
  • n_online + the number of players online +
  • +
  • all + list of all player on or offline +
  • +
  • n_all + the number of players who have joined the server +
  • +
  • admins_online + the number of admins online +
  • +
  • afk_players + the number of afk players +
  • +
  • times + the play times of every player +
  • +
+ + + + + +
+
+ + EmitEmbededParamaters +
+
+ Outline of the paramaters accepted by Sync.emit_embedded + + +

Fields:

+
    +
  • title + the tile of the embed +
  • +
  • color + the color given in hex you can use Color.to_hex{r=0,g=0,b=0} +
  • +
  • description + the description of the embed +
  • +
  • server_detail + sting to add onto the pre-set server detail +
  • +
  • fieldone + the filed to add to the embed (key is name) (value is text) (start value with <<inline>> to make inline) +
  • +
  • fieldtwo + the filed to add to the embed (key is name) (value is text) (start value with <<inline>> to make inline) +
  • +
+ + + + + +
+
+

Fields

+ +
+
+ + info +
+
+ used to get the global list that has been defined, also used to set that list + + +
    +
  • set + table + keys to be replaced in the server info + (default nil) +
  • +
+ + + + +

Usage:

+
    +
  • Sync.info{server_name='Factorio Server 2'} -- returns true
  • +
  • Sync.info -- table of info
  • +
+ +
+
+ + time +
+
+ Used to return and set the current IRL time; not very good need a better way to do this + + +
    +
  • set + string + the date time to be set + (default nil) +
  • +
+ + + + +

Usage:

+
    +
  • Sync.time('Sun Apr  1 18:44:30 UTC 2018')
  • +
  • Sync.time -- string
  • +
+ +
+
+

modules.expgamingcore.sync.src.gui Functions

+ +
+
+ + _comment () +
+
+ This file will be loaded when ExpGamingCore.Gui is present + + + + + + + +
+
+ + add_to_gui (element) +
+
+ Adds a emeltent to the sever info gui + + +

Parameters:

+
    +
  • element + see examples before for what can be used, it can also be a return from Gui.inputs.add +
  • +
+ +

Returns:

+
    + + bolean + based on weather it was successful or not +
+ + + +

Usage:

+
    +
    Sync.add_to_gui('string') -- return true
    +
+ +
+
+ + server-info +
+
+ Creates a center gui that will appear on join + + + + + + + +
+
+

modules.expgamingcore.sync.src.ranking Functions

+ +
+
+ + _comment () +
+
+ This file will be loaded when ExpGamingCore.Role is present + + + + + + + +
+
+ + set_ranks (...) +
+
+ Used as a redirect to Ranking._base_preset that will set the rank given to a player apon joining + + +

Parameters:

+
    +
  • ... + +
  • +
+ + + + +

Usage:

+
    +
    Sync.set_ranks{player_name=rank_name,...}
    +
+ +
+
+ + count_ranks () +
+
+ Used to get the number of players in each rank and currently online + + + +

Returns:

+
    + + table + contains the ranks and the players in that rank +
+ + + +

Usage:

+
    +
    Sync.count_ranks()
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/ExpGamingLib.html b/doc/modules/ExpGamingLib.html new file mode 100644 index 00000000..5cea1e8b --- /dev/null +++ b/doc/modules/ExpGamingLib.html @@ -0,0 +1,672 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module ExpGamingLib

+

Adds some common functions used though out all ExpGaming modules

+

+

Info:

+
    +
  • License: https://github.com/explosivegaming/scenario/blob/master/LICENSE
  • +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
unpack_to_G (tbl)Loads a table into _G even when sandboxed; will not overwrite values or append to tables; will not work during runtime to avoid desyncs
get_env ()Used to get the current ENV with all _G keys removed; useful when saving function to global
add_metatable (tbl[, callback=tostring[, string=table.tostring]])Creats a table that will act like a string and a function
is_type (v[, test_type=nil])Compear types faster for faster valadation of prams
player_return (rtn[, colour=defines.colour.white[, player=game.player]])Will return a value of any type to the player/server console, allows colour for in-game players
tick_to_hour (tick)Convert ticks to hours
tick_to_min (tick)Convert ticks to minutes
tick_to_display_format (tick)Converts a tick into a clean format for end user
gui_tree (root)Used as a way to view the structure of a gui, used for debuging
+

Class table

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
table.val_to_str (v)Returns a value in a form able to be read as a value, any value to string
table.key_to_str (k)Returns a value in a form able to be read as a key, any key to string
table.tostring (tbl)Returns a table in a form able to be read as a table
table.json (lua_table)Simmilar to table.tostring but converts a lua table to a json one
table.autokey (tbl, str)Returns the closest match to a key
table.alphanumsort (tbl)Returns the list is a sorted way that would be expected by people (this is by key)
table.keysort (tbl)Returns the list is a sorted way that would be expected by people (this is by key) (faster alterative than above)
+ +
+
+ + +

Functions

+ +
+
+ + unpack_to_G (tbl) +
+
+ Loads a table into _G even when sandboxed; will not overwrite values or append to tables; will not work during runtime to avoid desyncs + + +

Parameters:

+
    +
  • tbl + table + table to be unpacked +
  • +
+ + + + +

Usage:

+
    +
    unpack_to_G{key1='foo',key2='bar'}
    +
+ +
+
+ + get_env () +
+
+ Used to get the current ENV with all _G keys removed; useful when saving function to global + + + +

Returns:

+
    + + table + the env table with _G keys removed +
+ + + +

Usage:

+
    +
    get_env() returns current ENV with _G keys removed
    +
+ +
+
+ + add_metatable (tbl[, callback=tostring[, string=table.tostring]]) +
+
+ Creats a table that will act like a string and a function + + +

Parameters:

+
    +
  • tbl + table + the table that will have its metatable set +
  • +
  • callback + function + the function that will be used for the call + (default tostring) +
  • +
  • string + function or string + a function that resolves to a string or a string + (default table.tostring) +
  • +
+ +

Returns:

+
    + + table + the new table with its metatable set +
+ + + +

Usage:

+
    +
    add_metatable({},function) -- returns table
    +
+ +
+
+ + is_type (v[, test_type=nil]) +
+
+ Compear types faster for faster valadation of prams + + +

Parameters:

+
    +
  • v + the value to be tested +
  • +
  • test_type + string + the type to test for if not given then it tests for nil + (default nil) +
  • +
+ +

Returns:

+
    + + bolean + is v of type test_type +
+ + + +

Usage:

+
    +
  • is_type('foo','string') -- return true
  • +
  • is_type('foo') -- return false
  • +
+ +
+
+ + player_return (rtn[, colour=defines.colour.white[, player=game.player]]) +
+
+ Will return a value of any type to the player/server console, allows colour for in-game players + + +

Parameters:

+
    +
  • rtn + any value of any type that will be returned to the player or console +
  • +
  • colour + defines.color or string + the colour of the text for the player, ingroned when printing to console + (default defines.colour.white) +
  • +
  • player + LuaPlayer + the player that return will go to, if no game.player then returns to server + (default game.player) +
  • +
+ + + + +

Usage:

+
    +
  • player_return('Hello, World!') -- returns 'Hello, World!' to game.player or server console
  • +
  • player_return('Hello, World!','green') -- returns 'Hello, World!' to game.player with colour green or server console
  • +
  • player_return('Hello, World!',nil,player) -- returns 'Hello, World!' to the given player
  • +
+ +
+
+ + tick_to_hour (tick) +
+
+ Convert ticks to hours + + +

Parameters:

+
    +
  • tick + number + tick to convert to hours +
  • +
+ +

Returns:

+
    + + number + the number of whole hours from this tick +
+ + + +

Usage:

+
    +
    tick_to_hour(216001) -- return 1
    +
+ +
+
+ + tick_to_min (tick) +
+
+ Convert ticks to minutes + + +

Parameters:

+
    +
  • tick + number + tick to convert to minutes +
  • +
+ +

Returns:

+
    + + number + the number of whole minutes from this tick +
+ + + +

Usage:

+
    +
    tick_to_hour(3601) -- return 1
    +
+ +
+
+ + tick_to_display_format (tick) +
+
+ Converts a tick into a clean format for end user + + +

Parameters:

+
    +
  • tick + number + the tick to convert +
  • +
+ +

Returns:

+
    + + string + the formated string +
+ + + +

Usage:

+
    +
  • tick_to_display_format(3600) -- return '1.00 M'
  • +
  • tick_to_display_format(234000) -- return '1 H 5 M'
  • +
+ +
+
+ + gui_tree (root) +
+
+ Used as a way to view the structure of a gui, used for debuging + + +

Parameters:

+
    +
  • root + LuaGuiElement + the root to start the tree from +
  • +
+ +

Returns:

+
    + + table + the table that describes the gui +
+ + + +

Usage:

+
    +
    Gui_tree(root) returns all children of gui recusivly
    +
+ +
+
+

Class table

+ +
+ Extents the table class +
+
+
+ + table.val_to_str (v) +
+
+ Returns a value in a form able to be read as a value, any value to string + + +

Parameters:

+
    +
  • v + value to convert +
  • +
+ +

Returns:

+
    + + string + the converted value +
+ + + +

Usage:

+
    +
    table.val_to_str{a='foo'} -- return '"foo"'
    +
+ +
+
+ + table.key_to_str (k) +
+
+ Returns a value in a form able to be read as a key, any key to string + + +

Parameters:

+
    +
  • k + key to convert +
  • +
+ +

Returns:

+
    + + string + the converted key +
+ + + +

Usage:

+
    +
    table.val_to_str{a='foo'} -- return '["a"]'
    +
+ +
+
+ + table.tostring (tbl) +
+
+ Returns a table in a form able to be read as a table + + +

Parameters:

+
    +
  • tbl + table + table to convert +
  • +
+ +

Returns:

+
    + + string + the converted table +
+ + + +

Usage:

+
    +
    table.tostring{k1='foo',k2='bar'} -- return '{["k1"]="foo",["k2"]="bar"}'
    +
+ +
+
+ + table.json (lua_table) +
+
+ Simmilar to table.tostring but converts a lua table to a json one + + +

Parameters:

+
    +
  • lua_table + table + the table to convert +
  • +
+ +

Returns:

+
    + + string + the table in a json format +
+ + + +

Usage:

+
    +
    talbe.json{k1='foo',k2='bar'} -- return '{"k1":"foo","k2":"bar"}'
    +
+ +
+
+ + table.autokey (tbl, str) +
+
+ Returns the closest match to a key + + +

Parameters:

+
    +
  • tbl + table + the table that will be searched +
  • +
  • str + string + the string that will be looked for in the keys +
  • +
+ + + + +

Usage:

+
    +
    table.autokey({foo=1,bar=2},'f') -- return 1
    +
+ +
+
+ + table.alphanumsort (tbl) +
+
+ Returns the list is a sorted way that would be expected by people (this is by key) + + +

Parameters:

+
    +
  • tbl + table + the table to be sorted +
  • +
+ +

Returns:

+
    + + table + the sorted table +
+ + + +

Usage:

+
    +
    tbl = table.alphanumsort(tbl)
    +
+ +
+
+ + table.keysort (tbl) +
+
+ Returns the list is a sorted way that would be expected by people (this is by key) (faster alterative than above) + + +

Parameters:

+
    +
  • tbl + table + the table to be sorted +
  • +
+ +

Returns:

+
    + + table + the sorted table +
+ + + +

Usage:

+
    +
    tbl = table.alphanumsort(tbl)
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/FSM.html b/doc/modules/FSM.html new file mode 100644 index 00000000..ff5d0e35 --- /dev/null +++ b/doc/modules/FSM.html @@ -0,0 +1,455 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module FSM

+

Factorio Softmod Manager

+

+

Usage:

+
    +
    Manager = require("FactorioSoftmodManager")
    +
    +
+

Info:

+
    +
  • Author: Cooldude2606
  • +
+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_verbose (rtn)Default output for the verbose
verbose (rtn, action)Used to call the output of the verbose when the current state allows it
setVerbose (settings)Main logic for allowing verbose at different stages though out the script
sandbox (callback[, env])Creates a sand box envorment and runs a callback in that sand box; provents global pollution
loadModules ()Loads the modules that are present in the index list
error (err, callback)A more detailed replacement for the lua error function to allow for handlers to be added; repleaces default error so error can be used instead of Manager.error
event (event_name, callback)Event handler that modules can use, each module can register one function per event
+

Tables

+ + + + + + + + + +
verboseSettingsDifferent verbose settings used for setVerbose
Manager.event.namesSub set to Manger.event and acts as a coverter between event_name and event_id
+

Fields

+ + + + + +
globalUsed to avoid conflicts in the global table
+ +
+
+ + +

Functions

+ +
+
+ + _verbose (rtn) +
+
+ Default output for the verbose + + +

Parameters:

+
    +
  • rtn + string + the value that will be returned though verbose output +
  • +
+ + + + +

Usage:

+
    +
    Manager.verbose('Hello, World!')
    +
+ +
+
+ + verbose (rtn, action) +
+
+ Used to call the output of the verbose when the current state allows it + + +

Parameters:

+
    +
  • rtn + string + the value that will be returned though verbose output +
  • +
  • action + string + is used to decide which verbose this is error || event etc +
  • +
+ + + + +

Usage:

+
    +
    Manager.verbose('Hello, World!')
    +
+ +
+
+ + setVerbose (settings) +
+
+ Main logic for allowing verbose at different stages though out the script + + +

Parameters:

+
    +
  • settings + newTbl + the table that will be searched for settings to be updated +
  • +
+ + + + +

Usage:

+
    +
  • Manager.setVerbose{output=log}
  • +
  • Manager.setVerbose[setting] -- returns the value of that setting
  • +
  • tostring(Manager.setVerbose) -- returns a formated list of the current settings
  • +
+ +
+
+ + sandbox (callback[, env]) +
+
+ Creates a sand box envorment and runs a callback in that sand box; provents global pollution + + +

Parameters:

+
    +
  • callback + function + the function that will be ran in the sandbox +
  • +
  • env + any other params that the function will use + (optional) +
  • +
+ + + + +

Usage:

+
    +
  • Manager.sandbox(callback) -- return sandbox, success, other returns from callback
  • +
  • Manager.sandbox() -- returns and empty sandbox
  • +
  • Manager.sandbox[key] -- returns the sand box value in that key
  • +
+ +
+
+ + loadModules () +
+
+ Loads the modules that are present in the index list + + + + + + +

Usage:

+
    +
  • Manager.loadModules() -- loads all moddules in the index list
  • +
  • #Manager.loadModules -- returns the number of modules loaded
  • +
  • tostring(Manager.loadModules) -- returns a formatted list of all modules loaded
  • +
  • pairs(Manager.loadModules) -- loops over the loaded modules moduleName, module
  • +
+ +
+
+ + error (err, callback) +
+
+ A more detailed replacement for the lua error function to allow for handlers to be added; repleaces default error so error can be used instead of Manager.error + + +

Parameters:

+
    +
  • err + string or fucntion + the string to be passed to handlers; if a function it will register a handler +
  • +
  • callback + function + if given the err param will be used to given the handler a name +
  • +
+ + + + +

Usage:

+
    +
  • Manager.error(err) -- calls all error handlers that are set or if none then prints to game and if that fails crashs game
  • +
  • Manager.error() -- returns an error constant that can be used to crash game
  • +
  • Manager.error(Manager.error()) -- crashs the game
  • +
  • Manager.error.addHandler(name,callback) -- adds a new handler if handler returns Manager.error() then game will crash
  • +
  • Manager.error[name] -- returns the handler of that name if present
  • +
  • #Manager.error -- returns the number of error handlers that are present
  • +
  • pairs(Manager.error) -- loops over only the error handlers handler_name,hander
  • +
+ +
+
+ + event (event_name, callback) +
+
+ Event handler that modules can use, each module can register one function per event + + +

Parameters:

+
    +
  • event_name + int or string + that referes to an event +
  • +
  • callback + function + the function that will be set for that event +
  • +
+ + + + +

Usage:

+
    +
  • Manager.event[event_name] = callback -- sets the callback for that event
  • +
  • Manager.event[event_name] = nil -- clears the callback for that event
  • +
  • Manager.event(event_name,callback) -- sets the callback for that event
  • +
  • Manager.event[event_name] -- returns the callback for that event or the event id if not registered
  • +
  • Manager.event(event_name) -- runs all the call backs for that event
  • +
  • Manager.event() -- returns the stop value for the event proccessor, if returned during an event will stop all other callbacks
  • +
  • #Manager.event -- returns the number of callbacks that are registered
  • +
  • pairs(Manager.events) -- returns event_id,table of callbacks
  • +
+ +
+
+

Tables

+ +
+
+ + verboseSettings +
+
+ Different verbose settings used for setVerbose + + +

Fields:

+
    +
  • selfInit + boolean + called while the manager is being set up +
  • +
  • moduleLoad + boolean + when a module is required by the manager +
  • +
  • moduleInit + boolean + when and within the initation of a module +
  • +
  • moduleEnv + boolean + during module runtime, this is a global option set within each module(module_verbose=true ln:1) for fine control +
  • +
  • eventRegistered + boolean + when a module registers its event handlers +
  • +
  • errorCaught + boolean + when an error is caught during runtime +
  • +
  • output + function + can be: print || log || or other function +
  • +
  • _output + a constant value that can used to store output data +
  • +
+ + + + + +
+
+ + Manager.event.names +
+
+ Sub set to Manger.event and acts as a coverter between event_name and event_id + + + + + + +

Usage:

+
    +
    Manager.event[event_name]
    +
+ +
+
+

Fields

+ +
+
+ + global +
+
+ Used to avoid conflicts in the global table + + +
    +
  • if + table, string or true + table then the default for the global, if a string then the module to get the global of, if true then reset the global to default + (default {}) +
  • +
+ + + + +

Usage:

+
    +
  • global[key] -- used like the normal global table
  • +
  • global{'foo','bar'} -- sets the default value
  • +
  • global(true) -- restores global to default
  • +
  • global(mopdule_name) -- returns that module's global
  • +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/StdLib.Color.html b/doc/modules/StdLib.Color.html new file mode 100644 index 00000000..bec3d07b --- /dev/null +++ b/doc/modules/StdLib.Color.html @@ -0,0 +1,561 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module StdLib.Color

+

A defines module for retrieving colors by name.

+

+ Extends the Factorio defines table.

+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + +
set ([color=white[, alpha=1]])Set a value for the alpha channel in the given color table.
to_table (c_arr)Converts a color in the array format to a color in the table format.
from_rgb ([r=0[, g=0[, b=0[, a=255]]]])Converts a color in the rgb format to a color table
from_hex (hex[, alpha=1])Get a color table with a hexadecimal string.
to_rgb (color)Converts a color in the color table format to rgb
to_hex (color)Converts a color in the color table format to hex
+

Tables

+ + + + + + + + + + + + + + + + + +
defines.colorA table of colors allowing retrieval by color name.
defines.anticolorReturns white for dark colors or black for lighter colors.
defines.lightcolorReturns a lighter color of a named color
defines.textcolorReturns a lighter color of a named color.
+ +
+
+ + +

Functions

+ +
+
+ + set ([color=white[, alpha=1]]) +
+
+ Set a value for the alpha channel in the given color table. + `color.a` represents the alpha channel in the given color table. +
    +
  • If ***alpha*** is given, set `color.a` to it. +
  • If ***alpha*** is not given, and if the given color table does not have a value for `color.a`, set `color.a` to 1. +
  • If ***alpha*** is not given, and if the given color table already has a value for `color.a`, then leave `color.a` alone. +
+ + +

Parameters:

+
    +
  • color + defines.color or Concepts.Color + the color to configure + (default white) +
  • +
  • alpha + float + the alpha value (*[0 - 1]*) to set for the given color + (default 1) +
  • +
+ +

Returns:

+
    + + a + color table that has the specified value for the alpha channel +
+ + + + +
+
+ + to_table (c_arr) +
+
+ Converts a color in the array format to a color in the table format. + + +

Parameters:

+
    +
  • c_arr + table + the color to convert +
  • +
+ +

Returns:

+
    + + a + converted color — { r = c\_arr[1], g = c\_arr[2], b = c\_arr[3], a = c\_arr[4] } +
+ + + + +
+
+ + from_rgb ([r=0[, g=0[, b=0[, a=255]]]]) +
+
+ Converts a color in the rgb format to a color table + + +

Parameters:

+
    +
  • r + int + 0-255 red + (default 0) +
  • +
  • g + int + 0-255 green + (default 0) +
  • +
  • b + int + 0-255 blue + (default 0) +
  • +
  • a + int + 0-255 alpha + (default 255) +
  • +
+ +

Returns:

+
    + + Concepts.Color + +
+ + + + +
+
+ + from_hex (hex[, alpha=1]) +
+
+ Get a color table with a hexadecimal string. + Optionally provide the value for the alpha channel. + + +

Parameters:

+
    +
  • hex + string + hexadecimal color string (#ffffff, not #fff) +
  • +
  • alpha + float + the alpha value to set; such that ***[ 0 ⋜ value ⋜ 1 ]*** + (default 1) +
  • +
+ +

Returns:

+
    + + a + color table with RGB converted from Hex and with alpha +
+ + + + +
+
+ + to_rgb (color) +
+
+ Converts a color in the color table format to rgb + + +

Parameters:

+
    +
  • color + table + the color to convert +
  • +
+ +

Returns:

+
    + + table + the color as rgb +
+ + + + +
+
+ + to_hex (color) +
+
+ Converts a color in the color table format to hex + + +

Parameters:

+
    +
  • color + table + the color to convert +
  • +
+ +

Returns:

+
    + + string + the color as hex +
+ + + + +
+
+

Tables

+ +
+
+ + defines.color +
+
+ A table of colors allowing retrieval by color name. + + +

Fields:

+
    +
  • 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} +
  • +
+ + + + + +
+
+ + defines.anticolor +
+
+ Returns white for dark colors or black for lighter colors. + + +

Fields:

+
    +
  • green + defines.color.black +
  • +
  • grey + defines.color.black +
  • +
  • lightblue + defines.color.black +
  • +
  • lightgreen + defines.color.black +
  • +
  • lightgrey + defines.color.black +
  • +
  • lightred + defines.color.black +
  • +
  • orange + defines.color.black +
  • +
  • white + defines.color.black +
  • +
  • yellow + defines.color.black +
  • +
  • black + defines.color.white +
  • +
  • blue + defines.color.white +
  • +
  • brown + defines.color.white +
  • +
  • darkblue + defines.color.white +
  • +
  • darkgreen + defines.color.white +
  • +
  • darkgrey + defines.color.white +
  • +
  • darkred + defines.color.white +
  • +
  • pink + defines.color.white +
  • +
  • purple + defines.color.white +
  • +
  • red + defines.color.white +
  • +
+ + + + + +
+
+ + defines.lightcolor +
+
+ Returns a lighter color of a named color + + +

Fields:

+
    +
  • white + defines.color.lightgrey +
  • +
  • grey + defines.color.darkgrey +
  • +
  • lightgrey + defines.color.grey +
  • +
  • red + defines.color.lightred +
  • +
  • green + defines.color.lightgreen +
  • +
  • blue + defines.color.lightblue +
  • +
  • yellow + defines.color.orange +
  • +
  • pink + defines.color.purple +
  • +
+ + + + + +
+
+ + defines.textcolor +
+
+ Returns a lighter color of a named color. + + +

Fields:

+
    +
  • 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} +
  • +
+ + + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/StdLib.Game.html b/doc/modules/StdLib.Game.html new file mode 100644 index 00000000..627c73ad --- /dev/null +++ b/doc/modules/StdLib.Game.html @@ -0,0 +1,222 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module StdLib.Game

+

The game module.

+

+ + +

Functions

+ + + + + + + + + + + + + + + + + +
fail_if_missing (var[, msg="missing value"])Print msg if specified var evaluates to false.
get_player (mixed)Return a valid player object from event, index, string, or userdata
get_force (mixed)Return a valid force object from event, string, or userdata
print_all (msg[, condition])Messages all players currently connected to the game.
+ +
+
+ + +

Functions

+ +
+
+ + fail_if_missing (var[, msg="missing value"]) +
+
+ Print msg if specified var evaluates to false. + + +

Parameters:

+
    +
  • var + Mixed + variable to evaluate +
  • +
  • msg + string + message + (default "missing value") +
  • +
+ + + + + +
+
+ + get_player (mixed) +
+
+ Return a valid player object from event, index, string, or userdata + + +

Parameters:

+
    +
  • mixed + string, number, LuaPlayer or event + +
  • +
+ +

Returns:

+
    + + LuaPlayer + a valid player or nil +
+ + + + +
+
+ + get_force (mixed) +
+
+ Return a valid force object from event, string, or userdata + + +

Parameters:

+
    +
  • mixed + string, LuaForce or event + +
  • +
+ +

Returns:

+
    + + LuaForce + a valid force or nil +
+ + + + +
+
+ + print_all (msg[, condition]) +
+
+ 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. + + +

Parameters:

+
    +
  • msg + string + the message to send to players +
  • +
  • condition + nil or boolean + the condition to be true for a player to be messaged + (optional) +
  • +
+ +

Returns:

+
    + + uint + the number of players who received the message. +
+ + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/StdLib.String.html b/doc/modules/StdLib.String.html new file mode 100644 index 00000000..fe5de748 --- /dev/null +++ b/doc/modules/StdLib.String.html @@ -0,0 +1,302 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module StdLib.String

+

Extends Lua 5.2 string.

+

+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + +
trim (s)Returns a copy of the string with any leading or trailing whitespace from the string removed.
starts_with (s, start)Tests if a string starts with a given substring.
ends_with (s, ends)Tests if a string ends with a given substring.
contains (s, contains)Tests if a string contains a given substring.
is_empty (s)Tests whether a string is empty.
split (s[, sep="."[, pattern=false]])Splits a string into an array.
+ +
+
+ + +

Functions

+ +
+
+ + trim (s) +
+
+ Returns a copy of the string with any leading or trailing whitespace from the string removed. + + +

Parameters:

+
    +
  • s + string + the string to remove leading or trailing whitespace from +
  • +
+ +

Returns:

+
    + + string + a copy of the string without leading or trailing whitespace +
+ + + + +
+
+ + starts_with (s, start) +
+
+ Tests if a string starts with a given substring. + + +

Parameters:

+
    +
  • s + string + the string to check for the start substring +
  • +
  • start + string + the substring to test for +
  • +
+ +

Returns:

+
    + + boolean + true if the start substring was found in the string +
+ + + + +
+
+ + ends_with (s, ends) +
+
+ Tests if a string ends with a given substring. + + +

Parameters:

+
    +
  • s + string + the string to check for the end substring +
  • +
  • ends + string + the substring to test for +
  • +
+ +

Returns:

+
    + + boolean + true if the end substring was found in the string +
+ + + + +
+
+ + contains (s, contains) +
+
+ Tests if a string contains a given substring. + + +

Parameters:

+
    +
  • s + string + the string to check for the substring +
  • +
  • contains + string + the substring to test for +
  • +
+ +

Returns:

+
    + + boolean + true if the substring was found in the string +
+ + + + +
+
+ + is_empty (s) +
+
+ Tests whether a string is empty. + + +

Parameters:

+
    +
  • s + string + the string to test +
  • +
+ +

Returns:

+
    + + boolean + true if the string is empty +
+ + + + +
+
+ + split (s[, sep="."[, pattern=false]]) +
+
+ Splits a string into an array. + *Note:* Empty split substrings are not included in the resulting table. +

For example, `string.split("foo.bar...", ".", false)` results in the table `{"foo", "bar"}`. + + +

Parameters:

+
    +
  • s + string + the string to split +
  • +
  • sep + string + the separator to use. + (default ".") +
  • +
  • pattern + boolean + whether to interpret the separator as a lua pattern or plaintext for the string split + (default false) +
  • +
+ +

Returns:

+
    + + {string,...} + an array of strings +
+ + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/StdLib.Table.html b/doc/modules/StdLib.Table.html new file mode 100644 index 00000000..4c3d30c6 --- /dev/null +++ b/doc/modules/StdLib.Table.html @@ -0,0 +1,922 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module StdLib.Table

+

Extends Lua 5.2 table.

+

+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
map (tbl, func[, ...])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.
filter (tbl, func[, ...])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.
find (tbl, func[, ...])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.
any (tbl, func[, ...])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.
each (tbl, func[, ...])Given a function, apply it to each element in the table.
flatten (tbl[, level])Returns a new array that is a one-dimensional recursive flattening of the given array.
first (tbl)Given an array, returns the first element or nil if no element exists.
last (tbl)Given an array, returns the last element or nil if no elements exist.
min (tbl)Given an array of only numeric values, returns the minimum or nil if no element exists.
max (tbl)Given an array of only numeric values, returns the maximum or nil if no element exists.
sum (tbl)Given an array of only numeric values, return the sum of all values, or 0 for empty arrays.
avg (tbl)Given an array of only numeric values, returns the average or nil if no element exists.
merge (tblA, tblB[, array_merge=false])Merges two tables — values from first get overwritten by the second.
deepcopy (object)Creates a deep copy of table without copying Factorio objects.
values (tbl[, sorted[, as_string]])Returns a copy of all of the values in the table.
keys (tbl[, sorted[, as_string]])Returns a copy of all of the keys in the table.
remove_keys (tbl, keys)Removes keys from a table by setting the values associated with the keys to nil.
count_keys (tbl[, func[, ...]])Returns the number of keys in a table, if func is passed only count keys when the function is true.
invert (tbl)Returns an inverted (***{[value] = key,...}***) copy of the given table.
size (table)Return the size of a table using built in table_size function
arr_to_bool (tbl)For all string or number values in an array map them to a key = true table
+ +
+
+ + +

Functions

+ +
+
+ + map (tbl, func[, ...]) +
+
+ 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. + + +

Parameters:

+
    +
  • tbl + table + the table to be mapped to the transform +
  • +
  • func + function + the function to transform values +
  • +
  • ... + additional arguments passed to the function + (optional) +
  • +
+ +

Returns:

+
    + + table + a new table containing the keys and mapped values +
+ + + +

Usage:

+
    +
  • a= { 1, 2, 3, 4, 5}
    +table.map(a, function(v) return v * 10 end) --produces: { 10, 20, 30, 40, 50 }
  • +
  • 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}
  • +
+ +
+
+ + filter (tbl, func[, ...]) +
+
+ 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. + + +

Parameters:

+
    +
  • tbl + table + the table to be filtered +
  • +
  • func + function + the function to filter values +
  • +
  • ... + additional arguments passed to the function + (optional) +
  • +
+ +

Returns:

+
    + + table + a new table containing the filtered key-value pairs +
+ + + +

Usage:

+
    +
  • a= { 1, 2, 3, 4, 5}
    +table.filter(a, function(v) return v % 2 == 0 end) --produces: { 2, 4 }
  • +
  • a = {1, 2, 3, 4, 5}
    +table.filter(a, function(v, k, x) return k % 2 == 1 end) --produces: { 1, 3, 5 }
  • +
+ +
+
+ + find (tbl, func[, ...]) +
+
+ 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. + + +

Parameters:

+
    +
  • tbl + table + the table to be searched +
  • +
  • func + function + the function to use to search for any matching element +
  • +
  • ... + additional arguments passed to the function + (optional) +
  • +
+ +

Returns:

+
    + + nil or Mixed + the first found value, or nil if none was found +
+ + + +

Usage:

+
    +
  • a= { 1, 2, 3, 4, 5}
    +table.find(a, function(v) return v % 2 == 0 end) --produces: 2
  • +
  • a = {1, 2, 3, 4, 5}
    +table.find(a, function(v, k, x) return k % 2 == 1 end) --produces: 1
  • +
+ +
+
+ + any (tbl, func[, ...]) +
+
+ 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. + + +

Parameters:

+
    +
  • tbl + table + the table to be searched +
  • +
  • func + function + the function to use to search for any matching element +
  • +
  • ... + additional arguments passed to the function + (optional) +
  • +
+ +

Returns:

+
    + + boolean + true if an element was found, false if none was found +
+ + + +

Usage:

+
    +
  • a= { 1, 2, 3, 4, 5} table.any(a, function(v) return v % 2 == 0 end) --produces: true
  • +
  • a = {1, 2, 3, 4, 5} table.any(a, function(v, k, x) return k % 2 == 1 end) --produces: true
  • +
+ +
+
+ + each (tbl, func[, ...]) +
+
+ Given a function, apply it to each element in the table. + Passes the index as the second argument to the function. +

Iteration is aborted if the applied function returns true for any element during iteration. + + +

Parameters:

+
    +
  • tbl + table + the table to be iterated +
  • +
  • func + function + the function to apply to elements +
  • +
  • ... + additional arguments passed to the function + (optional) +
  • +
+ +

Returns:

+
    + + table + the table where the given function has been applied to its elements +
+ + + +

Usage:

+
    +
    a = {10, 20, 30, 40}
    +table.each(a, function(v) game.print(v) end) --prints 10, 20, 30, 40, 50
    +
+ +
+
+ + flatten (tbl[, level]) +
+
+ 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. +

The optional level argument determines the level of recursion to flatten. +> This function flattens an integer-indexed array, but not an associative array. + + +

Parameters:

+
    +
  • tbl + array + the array to be flattened +
  • +
  • level + uint + recursive levels, or no limit to recursion if not supplied + (optional) +
  • +
+ +

Returns:

+
    + + array + a new array that represents the flattened contents of the given array +
+ + + + +
+
+ + first (tbl) +
+
+ Given an array, returns the first element or nil if no element exists. + + +

Parameters:

+
    +
  • tbl + array + the array +
  • +
+ +

Returns:

+
    + + nil or Mixed + the first element +
+ + + + +
+
+ + last (tbl) +
+
+ Given an array, returns the last element or nil if no elements exist. + + +

Parameters:

+
    +
  • tbl + array + the array +
  • +
+ +

Returns:

+
    + + nil or Mixed + the last element or nil +
+ + + + +
+
+ + min (tbl) +
+
+ Given an array of only numeric values, returns the minimum or nil if no element exists. + + +

Parameters:

+
    +
  • tbl + {number,...} + the array with only numeric values +
  • +
+ +

Returns:

+
    + + nil or number + the minimum value +
+ + + + +
+
+ + max (tbl) +
+
+ Given an array of only numeric values, returns the maximum or nil if no element exists. + + +

Parameters:

+
    +
  • tbl + {number,...} + the array with only numeric values +
  • +
+ +

Returns:

+
    + + nil or number + the maximum value +
+ + + + +
+
+ + sum (tbl) +
+
+ Given an array of only numeric values, return the sum of all values, or 0 for empty arrays. + + +

Parameters:

+
    +
  • tbl + {number,...} + the array with only numeric values +
  • +
+ +

Returns:

+
    + + number + the sum of the numbers or zero if the given array was empty +
+ + + + +
+
+ + avg (tbl) +
+
+ Given an array of only numeric values, returns the average or nil if no element exists. + + +

Parameters:

+
    +
  • tbl + {number,...} + the array with only numeric values +
  • +
+ +

Returns:

+
    + + nil or number + the average value +
+ + + + +
+
+ + merge (tblA, tblB[, array_merge=false]) +
+
+ Merges two tables — values from first get overwritten by the second. + + +

Parameters:

+
    +
  • tblA + table + first table +
  • +
  • tblB + table + second table +
  • +
  • array_merge + boolean + set to true to merge the tables as an array or false for an associative array + (default false) +
  • +
+ +

Returns:

+
    + + array or table + an array or an associated array where tblA and tblB have been merged +
+ + + +

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
    +
+ +
+
+ + deepcopy (object) +
+
+ Creates a deep copy of table without copying Factorio objects. + + +

Parameters:

+
    +
  • object + table + the table to copy +
  • +
+ +

Returns:

+
    + + table + a copy of the table +
+ + + +

Usage:

+
    +
    local copy = table.deepcopy[data.raw.["stone-furnace"]["stone-furnace"]] -- returns a copy of the stone furnace entity
    +
+ +
+
+ + values (tbl[, sorted[, as_string]]) +
+
+ Returns a copy of all of the values in the table. + + +

Parameters:

+
    +
  • tbl + table + the table to copy the keys from, or an empty table if tbl is nil +
  • +
  • sorted + boolean + whether to sort the keys (slower) or keep the random order from pairs() + (optional) +
  • +
  • as_string + boolean + whether to try and parse the values as strings, or leave them as their existing type + (optional) +
  • +
+ +

Returns:

+
    + + array + an array with a copy of all the values in the table +
+ + + + +
+
+ + keys (tbl[, sorted[, as_string]]) +
+
+ Returns a copy of all of the keys in the table. + + +

Parameters:

+
    +
  • tbl + table + the table to copy the keys from, or an empty table if tbl is nil +
  • +
  • sorted + boolean + whether to sort the keys (slower) or keep the random order from pairs() + (optional) +
  • +
  • as_string + boolean + whether to try and parse the keys as strings, or leave them as their existing type + (optional) +
  • +
+ +

Returns:

+
    + + array + an array with a copy of all the keys in the table +
+ + + + +
+
+ + remove_keys (tbl, keys) +
+
+ Removes keys from a table by setting the values associated with the keys to nil. + + +

Parameters:

+
    +
  • tbl + table + the table to remove the keys from +
  • +
  • keys + {Mixed,...} + an array of keys that exist in the given table +
  • +
+ +

Returns:

+
    + + table + tbl without the specified keys +
+ + + +

Usage:

+
    +
  • local a = {1, 2, 3, 4}
    +table.remove_keys(a, {1,3}) --returns {nil, 2, nil, 4}
  • +
  • local b = {k1 = 1, k2 = 'foo', old_key = 'bar'}
    +table.remove_keys(b, {'old_key'}) --returns {k1 = 1, k2 = 'foo'}
  • +
+ +
+
+ + count_keys (tbl[, func[, ...]]) +
+
+ Returns the number of keys in a table, if func is passed only count keys when the function is true. + + +

Parameters:

+
    +
  • tbl + table + to count keys +
  • +
  • func + function + to incremement counter + (optional) +
  • +
  • ... + additional arguments passed to the function + (optional) +
  • +
+ +

Returns:

+
    +
  1. + number + The number of keys matching the function or the number of all keys if func isn't passed
  2. +
  3. + number + The total number of keys
  4. +
+ + + +

Usage:

+
    +
  • local a = { 1, 2, 3, 4, 5}
    + table.count_keys(a) -- produces: 5, 5
  • +
  • local a = {1, 2, 3, 4, 5}
    + table.count_keys(a, function(v, k) return k % 2 == 1 end) -- produces: 3, 5
  • +
+ +
+
+ + invert (tbl) +
+
+ 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(). + + +

Parameters:

+
    +
  • tbl + table + the table to invert +
  • +
+ +

Returns:

+
    + + table + a new table with inverted mapping +
+ + + +

Usage:

+
    +
  • local a = {k1 = 'foo', k2 = 'bar'}
    +table.invert(a) --returns {'foo' = k1, 'bar' = k2}
  • +
  • local b = {k1 = 'foo', k2 = 'bar', k3 = 'bar'}
    +table.invert(b) --returns {'foo' = k1, 'bar' = ?}
  • +
+ +
+
+ + size (table) +
+
+ Return the size of a table using built in table_size function + + +

Parameters:

+
    +
  • table + table + to use +
  • +
+ +

Returns:

+
    + + int + size of the table +
+ + + + +
+
+ + arr_to_bool (tbl) +
+
+ For all string or number values in an array map them to a key = true table + + +

Parameters:

+
    +
  • tbl + table + the table to convert +
  • +
+ +

Returns:

+
    + + table + the converted table +
+ + + +

Usage:

+
    +
    local a = {"v1", "v2"}
    + table.array_to_dict_bool(a) -- return {["v1"] = true, ["v2"]= true}
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/doc/modules/StdLib.Time.html b/doc/modules/StdLib.Time.html new file mode 100644 index 00000000..1730086b --- /dev/null +++ b/doc/modules/StdLib.Time.html @@ -0,0 +1,139 @@ + + + + + Reference + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module StdLib.Time

+

A defines module for retrieving the number of ticks in 1 unit of time.

+

+ Extends the Factorio defines table.

+ + +

Tables

+ + + + + +
defines.timeReturns the number of ticks in a second, minute, hour, day, week, month, or year.
+ +
+
+ + +

Tables

+ +
+
+ + defines.time +
+
+ Returns the number of ticks in a second, minute, hour, day, week, month, or year. + + +

Fields:

+
    +
  • second + the number of Factorio ticks in a second +
  • +
  • minute + the number of Factorio ticks in a second +
  • +
  • hour + the number of Factorio ticks in an hour +
  • +
  • day + the number of Factorio ticks in an day +
  • +
  • week + the number of Factorio ticks in a week +
  • +
  • month + the number of Factorio ticks in a month (30 days) +
  • +
  • year + the number of Factorio ticks in a year (365 days) +
  • +
+ + + + +

Usage:

+
    +
    local ten_seconds = defines.time.second * 10
    +
+ +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2018-06-07 12:58:23 +
+
+ + diff --git a/locale/de/DeconControl.cfg b/locale/de/DeconControl.cfg new file mode 100644 index 00000000..efab5765 --- /dev/null +++ b/locale/de/DeconControl.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=Du darfst dies noch nicht entfernen. Du benötigst dazu den Rang Regular, den du nach 3 Stunden auf dem Server automatisch erhältst. +rank-print=__1__ versuchte etwas zu entfernen. \ No newline at end of file diff --git a/locale/de/ExpGamingAdmin.AdminLib.cfg b/locale/de/ExpGamingAdmin.AdminLib.cfg new file mode 100644 index 00000000..299b094f --- /dev/null +++ b/locale/de/ExpGamingAdmin.AdminLib.cfg @@ -0,0 +1,15 @@ +[ExpGamingAdmin] +name=Admin-Befehle +tooltip=Die mächtigsten Befehle sind hier zuhause. +no-info-file=Die Informationsdatei wurde nicht gefunden. +message=Wähle einen Spieler und eine Aktion. Stell vor dem Ausführen sicher, dass der Richtige ist! +warning=Achtung, dieser Spieler hat einen höheren Rang als du selbst, weshalb du seinen Rang nicht ändern kannst. +short-reason=Achtung, dies ist ein sehr kurzer Grund. Bitte versuche, mehr Informationen anzugeben. (Warning: The reason is too short. UPDATE) +rank-high=Dieser Spieler hat einen hohen Rang. Bitte benutze nur Ingame-Befehle gegen diese Person, wenn du dir sicher bist! +invalid=Der Spieler oder die Aktion war ungültig. Bitte versuche es noch einmal! +take-action= Ergreife Maßnahme +tooltip-ban=Banne Spieler +tooltip-kick=Kicke Spieler +tooltip-jail=Sperre Spieler ins Gefängnis +tooltip-go-to=Gehe zum Spieler +tooltip-bring=Bringe den Spieler zu dir \ No newline at end of file diff --git a/locale/de/ExpGamingAdmin.Warnings.cfg b/locale/de/ExpGamingAdmin.Warnings.cfg new file mode 100644 index 00000000..c48f518a --- /dev/null +++ b/locale/de/ExpGamingAdmin.Warnings.cfg @@ -0,0 +1,11 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=This Warnings Was Given By: __1__ +player-warning=__1__ was given a warning by __2__ reason: __3__ +temp-ban=__1__ was temp-ban by __2__ and will remain in jail untill next reset +remove-warn=You are had a warning Removed, you have __1__ warnings, next removed in __2__ +message=You Are Currently Reciving Warnings From The Script, This Will Continue Unless You Cease And Desist +reported=You Have Been Reported To The Admins By The Script, Further Acction May Be Taken If You Do Not Cease And Desist. +kick-warn=You Are On A Warning To Be KICKED, The Script Will Auto Kick If You Do Not Cease And Desist. +temp-warn=You Are On A Warning To Be TEMP BANNED, The Script Will Auto Ban If You Do Not Cease And Desist. +ban-warn=You Are On A Warning To Be BANNED, The Script Will Auto Ban If You Do Not Cease And Desist. +last-warn=YOU ARE ON A LAST WARNING TO BE BANNED, THE SCRIPT WILL AUTO BAN IF YOU DO NOT CEASE AND DESIST. \ No newline at end of file diff --git a/locale/de/ExpGamingAdmin.cfg b/locale/de/ExpGamingAdmin.cfg new file mode 100644 index 00000000..299b094f --- /dev/null +++ b/locale/de/ExpGamingAdmin.cfg @@ -0,0 +1,15 @@ +[ExpGamingAdmin] +name=Admin-Befehle +tooltip=Die mächtigsten Befehle sind hier zuhause. +no-info-file=Die Informationsdatei wurde nicht gefunden. +message=Wähle einen Spieler und eine Aktion. Stell vor dem Ausführen sicher, dass der Richtige ist! +warning=Achtung, dieser Spieler hat einen höheren Rang als du selbst, weshalb du seinen Rang nicht ändern kannst. +short-reason=Achtung, dies ist ein sehr kurzer Grund. Bitte versuche, mehr Informationen anzugeben. (Warning: The reason is too short. UPDATE) +rank-high=Dieser Spieler hat einen hohen Rang. Bitte benutze nur Ingame-Befehle gegen diese Person, wenn du dir sicher bist! +invalid=Der Spieler oder die Aktion war ungültig. Bitte versuche es noch einmal! +take-action= Ergreife Maßnahme +tooltip-ban=Banne Spieler +tooltip-kick=Kicke Spieler +tooltip-jail=Sperre Spieler ins Gefängnis +tooltip-go-to=Gehe zum Spieler +tooltip-bring=Bringe den Spieler zu dir \ No newline at end of file diff --git a/locale/de/ExpGamingBot.autoChat.cfg b/locale/de/ExpGamingBot.autoChat.cfg new file mode 100644 index 00000000..32fea59f --- /dev/null +++ b/locale/de/ExpGamingBot.autoChat.cfg @@ -0,0 +1,20 @@ +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=You cant use global chat commands +players-online=There are __1__ players online +players=There have been __1__ players on this map +map-time=This map has been on for __1__ +line-8=Type /help for more info +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) +not-real-dev=Cooldude2606 is a dev for this server and makes the softmod (look top left) and is not a factorio dev. +softmod=A softmod is a custom scenario that runs on this server, example is the player list. +blame=Blame __1__ for what just happend! +afk=Your afk? Look at __1__ they have been afk for: __2__ +links=To see links open the readme and click links. +magic=Fear the admin magic (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) \ No newline at end of file diff --git a/locale/de/ExpGamingBot.autoMessage.cfg b/locale/de/ExpGamingBot.autoMessage.cfg new file mode 100644 index 00000000..49d19ede --- /dev/null +++ b/locale/de/ExpGamingBot.autoMessage.cfg @@ -0,0 +1,9 @@ +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=There are __1__ players online +map-time=This map has been on for __1__ +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) \ No newline at end of file diff --git a/locale/de/ExpGamingCore.Command.cfg b/locale/de/ExpGamingCore.Command.cfg new file mode 100644 index 00000000..1ea17d9b --- /dev/null +++ b/locale/de/ExpGamingCore.Command.cfg @@ -0,0 +1,9 @@ +[ExpGamingCore_Command] +unauthorized=401 - Unbefugt: Zugang verweigert. Du hast keinen Zugriff auf diese Befehle! +invalid-inputs=ungültige Eingabe, /__1__ __2__ +invalid-range=ungültige Reichweite, Min: __1__, Max: __2__ +invalid-length=ungültige Länge, Max: __1__ +invalid-player=ungültiger Spieler Name, __1__ , Versuche "Tab" zu benutzen, damit sich der Name automatisch vervollständigt. +offline-player=Der betroffene Spieler ist offline, Befehl konnte nicht ausgeführt werden. +dead-player=Der betroffene Spieler ist Tod, Befehl konnte nicht ausgeführt werden. +command-ran=Befehl ausgeführt. \ No newline at end of file diff --git a/locale/de/ExpGamingCore.Commands.cfg b/locale/de/ExpGamingCore.Commands.cfg new file mode 100644 index 00000000..1ea17d9b --- /dev/null +++ b/locale/de/ExpGamingCore.Commands.cfg @@ -0,0 +1,9 @@ +[ExpGamingCore_Command] +unauthorized=401 - Unbefugt: Zugang verweigert. Du hast keinen Zugriff auf diese Befehle! +invalid-inputs=ungültige Eingabe, /__1__ __2__ +invalid-range=ungültige Reichweite, Min: __1__, Max: __2__ +invalid-length=ungültige Länge, Max: __1__ +invalid-player=ungültiger Spieler Name, __1__ , Versuche "Tab" zu benutzen, damit sich der Name automatisch vervollständigt. +offline-player=Der betroffene Spieler ist offline, Befehl konnte nicht ausgeführt werden. +dead-player=Der betroffene Spieler ist Tod, Befehl konnte nicht ausgeführt werden. +command-ran=Befehl ausgeführt. \ No newline at end of file diff --git a/locale/de/ExpGamingCore.Gui.cfg b/locale/de/ExpGamingCore.Gui.cfg new file mode 100644 index 00000000..fbdba2f7 --- /dev/null +++ b/locale/de/ExpGamingCore.Gui.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 - Unbefugt: Du hast keinen Zugriff auf diese Befehle! +cant-open=Du kannst dieses Menü nicht öffnen, Grund: __1__ +cant-open-no-reason=Du kannst dieses Menü gerade nicht öffnen. \ No newline at end of file diff --git a/locale/de/ExpGamingCore.Ranking.cfg b/locale/de/ExpGamingCore.Ranking.cfg new file mode 100644 index 00000000..8889c096 --- /dev/null +++ b/locale/de/ExpGamingCore.Ranking.cfg @@ -0,0 +1,7 @@ +[ranking] +all-rank-print=[Alle]: __1__ +rank-print=[__1__]: __2__ +rank-up=__1__ wurde befördert zu __2__ von __3__ +rank-down=__1__ wurde degradiert zu __2__ von __3__ +rank-given=Dir wurde der Rang __1__ zugeteilt! +tag-reset=Dein Spitzname wurde aufgrund eines Rangwechsels zurückgesetzt. \ No newline at end of file diff --git a/locale/de/ExpGamingInfo.Readme.cfg b/locale/de/ExpGamingInfo.Readme.cfg new file mode 100644 index 00000000..4fc2512b --- /dev/null +++ b/locale/de/ExpGamingInfo.Readme.cfg @@ -0,0 +1,68 @@ +[ExpGamingInfo-Readme] +tooltip=Open the readme gui that opens when you first join. +guildlines-name=Guild Lines +guildlines-tooltip=These are the guildlines you should follow +guildlines-line1=Welcome to the Explosive Gaming Community! +guildlines-line2= +guildlines-line3=Here are some guidelines to keep this Server fun for everyone: +guildlines-line4=- Hacking / cheating / abusing bugs will not be tolerated. +guildlines-line5=- Be polite and use common sense. +guildlines-line6=- Nobody likes spam. That includes: Chat, Bots, unlimited Chests and Concrete. +guildlines-line7=- Do not remove stuff without even trying to talk / ask about it. +guildlines-line8=- Trains: LHD (Left hand drive), no Loops and use them for long distances. (- Trains are only allowed in LHD (Left Hand Drive). Train loops. UPDATE) +guildlines-line9= +guildlines-line10=If you have any questions about the rules, the server or the game in general, feel free to ask. Have Fun! +chat-name=How To Chat +chat-tooltip=How to chat in factorio with default key config +chat-singleline=Chatting can be difficult for new players because it’s different than other games! It’s very simple, the button you need to press is the “GRAVE/TILDE” key it’s located under the “ESC key”. If you would like to change the key go to your controls tab in options. The key you need to change is “Toggle Lua console” it’s located in the second column 2nd from bottom. +commands-name=Commands +commands-tooltip=These are the commands you can use +commands-singleline=These are the many diffrent custom commands you are able to use, the base game commands are not shown +commands-col1=Command Name +commands-col2=Command Help +links-name=Links +links-tooltip=Helpful links for ways to get in touch +links-cap1=Discord voice and chat server: +links-cap2=Our website: +links-cap3=Steam: +links-cap4=Patreon: +servers-name=Servers +servers-tooltip=Info on our other servers +servers-singleline=Welcome to the Explosive Gaming Community! S1-S3 are staggered resets. +servers-format=S__1__: __2__ +servers-cap1=Public +servers-des1=A place for all players, this map reset every 144H At 16:00 UTC. +servers-cap2=Public +servers-des2=A place for all players, this map reset every 144H At 16:00 UTC. +servers-cap3=Public +servers-des3=A place for all players, this map reset every 144H At 16:00 UTC. +servers-cap4=Modded +servers-des4=A modded server not much to say, just download the mods to play. Link on Discord for members. +servers-cap5=Events +servers-des5=Sometimes we hold events, may require a password, join discord for more info. +servers-cap6=Donator +servers-des6=For those people who have two much money and give us some. Anything goes per request. +rules-name=All Rules +rules-tooltip=A full list of rules for the server +rules-singleline=This is a full list of rules what must be followed, the guildlines will cover most points in here but for those who like to follow the rules word to word then here is the full list. +rules-format=__1__) __2__ +rules-rule1=Hacking/cheating, exploiting and abusing bugs is not allowed. +rules-rule2=Any bugs or exploits found should be reported. (no creative items) +rules-rule3=Do not disrespect any player in the server. +rules-rule4=Do not take every item frmo a belt or via logics request, share resources. +rules-rule5=Do not spam, this includes stuff such as chat spam, item spam, chest spam etc. +rules-rule6=Do not laydown or remove concrete or stone with bots without permission. +rules-rule7=Do not use active provider chests without permission. +rules-rule8=Do not use speakers on global or with alearts without permission. +rules-rule9=Do not remove/move major parts of the factory without permission. +rules-rule10=Do not walk in player random direction for no reason(to save map size). +rules-rule11=Do not remove stuff just because you dont like it, tell people first. +rules-rule12=Do not rotate belts, deactive belts with wires, or cause production to stop. +rules-rule13=Do not make train roundabouts. Or any loops of any kind. +rules-rule14=When using trains use the same size that others have used. +rules-rule15=Trains are Left Hand Drive (LHD) only. +rules-rule16=Do not complain about lag, low fps and low ups or other things like that. +rules-rule17=Do not ask for rank, our ranks are synced with discord, admins cant give ranks. +rules-rule18=Do not advertise other servers unless you are a trusted server owner. +rules-rule19=Report any one who breaks the rules. +rules-rule20=Use common sense and what an admin says goes. diff --git a/locale/de/ExpGamingInfo.Rockets.cfg b/locale/de/ExpGamingInfo.Rockets.cfg new file mode 100644 index 00000000..8fd5471e --- /dev/null +++ b/locale/de/ExpGamingInfo.Rockets.cfg @@ -0,0 +1,12 @@ +[ExpGamingInfo-Rockets] +name=Raketeninfo +tooltip=Detailliste über gestartete Raketen. +none=Es wurden noch keine Rakten gestartet. +nan=NaN +sent=Gestartete Raketen: __1__ +first=Erster Start: __1__ +last=Dauer bis zum letzten Start: __1__ +time=Durchschnittliche Starzeit: __1__ +fastest=Schnellster Start: __1__ +milestones=Meilensteine: +format=__1__: __2__ \ No newline at end of file diff --git a/locale/de/ExpGamingInfo.Science.cfg b/locale/de/ExpGamingInfo.Science.cfg new file mode 100644 index 00000000..e10b31a4 --- /dev/null +++ b/locale/de/ExpGamingInfo.Science.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Wissenschaftsinfo +tooltip=Detailliste über Wissenschaftspakete +total=Gemachte Pakete: +time=Pakete pro Minute: +format=__1__: __2__ +science-pack-1=Rot +science-pack-2=Grün +science-pack-3=Blau +military-science-pack=Militär +production-science-pack=Produktion +high-tech-science-pack=Hochtechnologie +space-science-pack=Weltraum +none=Es wurden noch keine Wissenschaftspakete gemacht. \ No newline at end of file diff --git a/locale/de/ExpGamingInfo.Tasklist.cfg b/locale/de/ExpGamingInfo.Tasklist.cfg new file mode 100644 index 00000000..48573724 --- /dev/null +++ b/locale/de/ExpGamingInfo.Tasklist.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Taskliste +tooltip=Welche Aufgaben müssen rund um die Fabrik erledigt werden? +none=Es sind aktuell keine Tasks erfasst, frage einen Member um einen hinzuzufügen. \ No newline at end of file diff --git a/locale/de/ExpGamingPlayer.inventorySearch.cfg b/locale/de/ExpGamingPlayer.inventorySearch.cfg new file mode 100644 index 00000000..895707f4 --- /dev/null +++ b/locale/de/ExpGamingPlayer.inventorySearch.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Dein Inventar wurde durchsucht und __1__ wurde entfernt. +med=Dein Inventar wurde durchsucht und __1__ wurde entfernt. Dir wird hiermit eine Warnung erteilt! Versuche es nicht erneut! +high=Dein inventar wurde durchsucht und __1__ wurde gefunden, dies ist auf GAR KEINEN Fall erlaubt, dein Inventar wurde zum Spawnpunkt transferiert. \ No newline at end of file diff --git a/locale/de/ExpGamingPlayer.playerInfo.cfg b/locale/de/ExpGamingPlayer.playerInfo.cfg new file mode 100644 index 00000000..1d52251f --- /dev/null +++ b/locale/de/ExpGamingPlayer.playerInfo.cfg @@ -0,0 +1,8 @@ +[ExpGamingPlayer-playerInfo] +yes=Ja +no=Nein +name=[__1__] __2__ +online=Ist online: __1__ (__2__) +admin=Hat Admin Rang: __1__ +group=In Benutzer Gruppe: __1__ +role=Hat Rang: __1__ \ No newline at end of file diff --git a/locale/de/ExpGamingPlayer.playerList.cfg b/locale/de/ExpGamingPlayer.playerList.cfg new file mode 100644 index 00000000..ed48069f --- /dev/null +++ b/locale/de/ExpGamingPlayer.playerList.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Verkleinere die Spielerliste. Rechtsklicke einen Spieler für Informationen über ihn. +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=Es wurden keine Informationen gefunden. \ No newline at end of file diff --git a/locale/de/ExpGamingPlayer.polls.cfg b/locale/de/ExpGamingPlayer.polls.cfg new file mode 100644 index 00000000..b476a903 --- /dev/null +++ b/locale/de/ExpGamingPlayer.polls.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Umfragen +tooltip=Alte Umfragen ansehen +no-poll=Keine alten Umfragen +end=Die Umfrage hat gerade geendet: __1__ +winner=__1__ hatte die meisten Stimmen. +time-left=Du hast noch __1__s um deine Wahl zu erfassen. \ No newline at end of file diff --git a/locale/de/GameSettingsGui.cfg b/locale/de/GameSettingsGui.cfg new file mode 100644 index 00000000..dece78e7 --- /dev/null +++ b/locale/de/GameSettingsGui.cfg @@ -0,0 +1,31 @@ +[GameSettingsGui] +name=Spieleinstellungen +tooltip=Erlaubt das Modifizieren von Spieleinstellungen. Bitte mit Bedacht benutzen. +basic-name=Einfache Einstellungen +basic-tooltip=Diese Einstellungen sind ohne Probleme veränderbar, sie verursachen keine großen Probleme im nachhinein. +basic-message=Dies sind fraktionsweite Einstellungen, welche genutzt werden können um das Spiel zu vereinfachen und es für Alle angenehmer zu machen. +advanced-name=Erweiterte Einstellungen +advanced-tooltip=Diese Einstellungen sollten nicht von Leuten benutzt werden, die nicht wissen was sie tun. +advanced-message=Bitte ändere keine dieser Einstellungen ausser du bist dir 100% sicher was sie tun,lass game.speed allein, da es einen viel größeren Effekt hat als du denkst. +personal-name=Persönliche Einstellungen +personal-tooltip=Diese Einstellungen betreffen nur deinen Spieler. Wenn man dich beim cheaten erwischt bist du auf dich allein gestellt. +personal-message=Diese Einstellungen betreffen nur deinen Spieler, übertreib es nicht ansonsten besteht die Gefahr, dass dich normale Spieler (gierige Kleinkinder) dabei erwischen (und rumheulen). +sure=Bist du dir Sicher?! +effect-mining-speed=Abbaugeschwindigkeit +effect-craft-speed=Herstellgeschwindigkeit +effect-running-speed=Laufgeschwindigkeit +effect-build-distance=Baudistanz +effect-reach-distance=Armreichweite +effect-bot-speed=Robotergeschwindigkeit +effect-lab-speed=Laborgeschwindigkeit +effect-stack-bonus=Stapelnonuss +effect-quickbar-count=Anzahl Schnellleistenelemente +effect-inventory-size=Inventargröße +effect-mining-prod=Abbauproduktivität +effect-game-speed=Spielgeschwindigkeit +effect-save=Spiel speichern +effect-reload-effects=Effekte neu laden +effect-reload-map=Minimap neu laden +effect-kill-biters=Töte alle Beisser +effect-crc=Forciere CRC check +effect-reset-force=Fraktion zurücksetzen \ No newline at end of file diff --git a/locale/de/GuiAnnouncements.cfg b/locale/de/GuiAnnouncements.cfg new file mode 100644 index 00000000..9744da36 --- /dev/null +++ b/locale/de/GuiAnnouncements.cfg @@ -0,0 +1,6 @@ +[GuiAnnouncements] +name=Ankündigung +tooltip=Eine Ankündigung an Spieler senden +sent-to=Dies wurde zu __1__ gesendet +sent-by=Dies wurde von __1__ mit Rang __2__ gesendet +select-rank=Diese Nachricht wird gesendet an: \ No newline at end of file diff --git a/locale/de/WarpPoints.cfg b/locale/de/WarpPoints.cfg new file mode 100644 index 00000000..fac81895 --- /dev/null +++ b/locale/de/WarpPoints.cfg @@ -0,0 +1,9 @@ +[WarpPoints] +name=Warp List +tooltip=Die Liste mit den Warp-Punkten +remove-tooltip=Entferne Warp-Punkt +go-to-tooltip=Gehe zu Warp-Punkt +cooldown=Warte, bis der Cooldown abgelaufen ist. Verbleibende Zeit: __1__ +cooldown-zero=Dein Cooldown ist abgelaufen, du kannst jetzt wieder Warp-Punkte verwenden. +name-used=Dieser Name ist schon vergeben. +not-on-warp=Du bist nicht auf einem Warp-Punkt. Gehe auf einen Warp-Punkt, um zu einem anderen zu springen. \ No newline at end of file diff --git a/locale/en/DeconControl.cfg b/locale/en/DeconControl.cfg new file mode 100644 index 00000000..556c1f3a --- /dev/null +++ b/locale/en/DeconControl.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=You do not have permission to do this right now. You require the Regular rank which can be obtained through 3 hours of in-game playtime on a server. +rank-print=__1__ tried to deconstruct something. diff --git a/locale/en/ExpGamingAdmin.AdminLib.cfg b/locale/en/ExpGamingAdmin.AdminLib.cfg new file mode 100644 index 00000000..f240bac1 --- /dev/null +++ b/locale/en/ExpGamingAdmin.AdminLib.cfg @@ -0,0 +1,21 @@ +[ExpGamingAdmin] +name=Admin Commands +tooltip=Admin commands make their home here +no-info-file=No info file was found +message=Please select a player and an action to take. Make sure to choose the correct one! +warning=Warning: This player outranks you. Therefore, you cannot edit their rank. +short-reason=Warning: The reason is too short. +rank-high=Warning: This player outranks you. Therefore, you cannot edit their rank. +invalid=The player or the action is invalid. Please try again! +take-action=Take Action +tooltip-ban=Ban Player +tooltip-kick=Kick Player +tooltip-jail=Jail Player +tooltip-go-to=Go To Player +tooltip-bring=Bring Player +temp-ban=__1__ was temporary banned by __2__ and will remain in jail until next reset +report=Report Player +cant-report-ban=Invalid player as player is banned; Either unban or use /clear-all +low-print=__1__ has been reported by a user for: __2__ +high-print=__1__ has been reported by __2__ for: __3__ +cant-report=This player can't be reported. \ No newline at end of file diff --git a/locale/en/ExpGamingAdmin.Warnings.cfg b/locale/en/ExpGamingAdmin.Warnings.cfg new file mode 100644 index 00000000..01715fc7 --- /dev/null +++ b/locale/en/ExpGamingAdmin.Warnings.cfg @@ -0,0 +1,10 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=This warning was given by: __1__ +player-warning=__1__ was given a warning by __2__ for: __3__ +remove-warn=One of your warnings expired. You have __1__ warnings left, next warning will be removed in __2__ +message=You are currently being warned by the system. These will continue until you cease and desist. +reported=You have been reported to the admins by the system. Further action may be taken if you do not cease and desist. +kick-warn=This is your last warning before you get kicked. The system will automatically kick you if you do not cease and desist. +temp-warn=This is your last warning before you get temporary banned. The system will automatically ban you if you do not cease and desist. +ban-warn=WARNING: This is your last warning before you get BANNED. The system will automatically BAN you if you do not cease and desist. +last-warn=WARNING: This is your last warning before you get PERMANENTLY BANNED. The system will automatically PERMANENTLY BAN you if you do not cease and desist. diff --git a/locale/en/ExpGamingAdmin.cfg b/locale/en/ExpGamingAdmin.cfg new file mode 100644 index 00000000..f240bac1 --- /dev/null +++ b/locale/en/ExpGamingAdmin.cfg @@ -0,0 +1,21 @@ +[ExpGamingAdmin] +name=Admin Commands +tooltip=Admin commands make their home here +no-info-file=No info file was found +message=Please select a player and an action to take. Make sure to choose the correct one! +warning=Warning: This player outranks you. Therefore, you cannot edit their rank. +short-reason=Warning: The reason is too short. +rank-high=Warning: This player outranks you. Therefore, you cannot edit their rank. +invalid=The player or the action is invalid. Please try again! +take-action=Take Action +tooltip-ban=Ban Player +tooltip-kick=Kick Player +tooltip-jail=Jail Player +tooltip-go-to=Go To Player +tooltip-bring=Bring Player +temp-ban=__1__ was temporary banned by __2__ and will remain in jail until next reset +report=Report Player +cant-report-ban=Invalid player as player is banned; Either unban or use /clear-all +low-print=__1__ has been reported by a user for: __2__ +high-print=__1__ has been reported by __2__ for: __3__ +cant-report=This player can't be reported. \ No newline at end of file diff --git a/locale/en/ExpGamingBot.autoChat.cfg b/locale/en/ExpGamingBot.autoChat.cfg new file mode 100644 index 00000000..4afb021d --- /dev/null +++ b/locale/en/ExpGamingBot.autoChat.cfg @@ -0,0 +1,48 @@ +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=You can't use global chat commands +players-online=There are __1__ players online +players=There have been __1__ players on this map +map-time=This map has been on for __1__ +line-8=Type /help for more info +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: https://www.explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (It can be found through the question mark on the top left) +not-real-dev=Cooldude2606 is a dev for this server and makes the softmod (look top left) and is not a factorio dev. +softmod=A softmod is a custom scenario that runs on this server, example is the player list. +redmew=We dont talk about redmew here; they beat us to 1000 members; F +blame=Blame __1__ for what just happend! +afk=Your afk? Look at __1__, that player has been afk for: __2__ +links=To see links open the readme and click links. +current-evolution=Current evolution factor is __1__ +magic=Fear the admin magic (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) +loops=NO LOOPS; LOOPS ARE BAD; JUST NO LOOPS!!!!!; IF YOU MAKE A LOOP.... IT WILL NOT END WELL!!!!!!! +lenny=( ͡° ͜ʖ ͡°) +make-tea-1= ☕ Boiling the water... ☕ +make-tea-2= ☕ __1__ your tea is done! ☕ +order-pizza-1= 🍕 Finding nearest pizza supplier... 🍕 +order-pizza-2= 🍕 Figuring out the favourite pizza of __1__ 🍕 +order-pizza-3= 🍕 __1__ your pizza is here! 🍕 +make-coffee-1= ☕ Boiling the water and grinding the coffee beans... ☕ +make-coffee-2= ☕ __1__ we ran out of coffe beans! Have some tea instead. ☕ +get-beer-1= 🍺 Pouring A Glass 🍺 +get-beer-2= 🍻 Chears Mate 🍻 +get-mead-1= Filling the drinking horn +get-mead-2= Skål! +get-snaps-1=Pouring the glasses and finding the correct song book... +get-snaps-2=Singing a song...🎤🎶 +get-snaps-3=skål, my friends! +get-cocktail-1= 🍸 Inintiating mind reading unit... 🍸 +get-cocktail-2= 🍸 Mixing favourite ingredients of __1__ 🍸 +get-cocktail-3=🍸 __1__ your cocktail is done.🍸 +lhd=All trains must be LHD! +food=Don't know what to make for dinner? Use a random recipe from the random dinner suggestion generator at http://www.whatthefuckshouldimakefordinner.com/ +get-popcorn-1=Heating the oil and waiting for the popping sound... +get-popcorn-2=__1__ your popcorn is finished. Lean backwards and watch the drama unfold. +wiki=You can get more information about us and the custom scenario from our wiki: https://wiki.explosivegaming.nl/ +feedback=Do you have feedback? leave it at https://exp.fider.io/ +hodor=Hodor \ No newline at end of file diff --git a/locale/en/ExpGamingBot.autoMessage.cfg b/locale/en/ExpGamingBot.autoMessage.cfg new file mode 100644 index 00000000..c67078a9 --- /dev/null +++ b/locale/en/ExpGamingBot.autoMessage.cfg @@ -0,0 +1,9 @@ +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=There are __1__ players online +map-time=This map has been on for __1__ +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: https://www.explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (It can be found through the question mark on the top left) \ No newline at end of file diff --git a/locale/en/ExpGamingCommands.home.cfg b/locale/en/ExpGamingCommands.home.cfg new file mode 100644 index 00000000..e70a2161 --- /dev/null +++ b/locale/en/ExpGamingCommands.home.cfg @@ -0,0 +1,9 @@ +[ExpGamingCommands-home] +too-many-homes=You have too many homes, to add more you must remove one. Your max is __1__. +homes=Your Homes: (__1__/__2__) +home=__1__) __2__: __3__ , __4__ +set=Your home "__1__" as been set to __2__ , __3__ +remove=Your home "__1__" as been removed +goto=You are now at "__1__" +return=You are now at your previous location: __1__ , __2__ +invalid=Invalid name, __1__ \ No newline at end of file diff --git a/locale/en/ExpGamingCore.Command.cfg b/locale/en/ExpGamingCore.Command.cfg new file mode 100644 index 00000000..bdc9fb41 --- /dev/null +++ b/locale/en/ExpGamingCore.Command.cfg @@ -0,0 +1,14 @@ +[ExpGamingCore_Command] +unauthorized=Unauthorized, Access is denied due to invalid credentials +error-string-list=Invalid Option, Must be one of: __1__ +error-string-len=Invalid Length, Max: __1__ +error-number=Invalid Number +error-number-range=Invalid Range, Min (exclusive): __1__, Max (inclusive): __2__ +error-player=Invaild Player Name, __1__ ,try using tab key to auto-complete the name +error-player-online=Player is offline. +error-player-alive=Player is dead. +error-player-rank=Player is of Higher Rank. +invalid-inputs=Invalid Input, /__1__ __2__ +invalid-parse=Invalid Input, There was a problem prasing the paramaters +command-ran=Command Complete +command-fail=Command failed to run: __1__ \ No newline at end of file diff --git a/locale/en/ExpGamingCore.Gui.cfg b/locale/en/ExpGamingCore.Gui.cfg new file mode 100644 index 00000000..f7eb1a6a --- /dev/null +++ b/locale/en/ExpGamingCore.Gui.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 - Unauthorized: Access is denied due to invalid credentials +cant-open=You can't open this panel right now, reason: __1__ +cant-open-no-reason=You can't open this panel right now \ No newline at end of file diff --git a/locale/en/ExpGamingCore.Ranking.cfg b/locale/en/ExpGamingCore.Ranking.cfg new file mode 100644 index 00000000..dc641783 --- /dev/null +++ b/locale/en/ExpGamingCore.Ranking.cfg @@ -0,0 +1,7 @@ +[ranking] +all-rank-print=[Everyone]: __1__ +rank-print=[__1__]: __2__ +rank-up=__1__ was promoted to __2__ by __3__ +rank-down=__1__ was demoted to __2__ by __3__ +rank-given=You have been given the __1__ Rank! +tag-reset=Your Tag was reset due to a Rank change \ No newline at end of file diff --git a/locale/en/ExpGamingCore.Role.cfg b/locale/en/ExpGamingCore.Role.cfg new file mode 100644 index 00000000..4cb41594 --- /dev/null +++ b/locale/en/ExpGamingCore.Role.cfg @@ -0,0 +1,6 @@ +[ExpGamingCore-Role] +default-print=[Everyone]: __1__ +print=[__1__]: __2__ +assign=__1__ was assigned to __2__ by __3__ +unassign=__1__ was unassigned from __2__ by __3__ +tag-reset=Your Tag was reset due to a role change \ No newline at end of file diff --git a/locale/en/ExpGamingCore.Server.cfg b/locale/en/ExpGamingCore.Server.cfg new file mode 100644 index 00000000..e70ede54 --- /dev/null +++ b/locale/en/ExpGamingCore.Server.cfg @@ -0,0 +1,2 @@ +[ExpGamingCore_Server] +interface-description=Runs the given input from the script \ No newline at end of file diff --git a/locale/en/ExpGamingInfo.Readme.cfg b/locale/en/ExpGamingInfo.Readme.cfg new file mode 100644 index 00000000..086261eb --- /dev/null +++ b/locale/en/ExpGamingInfo.Readme.cfg @@ -0,0 +1,69 @@ +[ExpGamingInfo-Readme] +tooltip=Open the ReadMe if this is your first time joining. +guildlines-name=Guidelines +guildlines-tooltip=These are the guidelines everyone should follow +guildlines-line1=Welcome to the Explosive Gaming Community! +guildlines-line2=Here are some guidelines that everyone is obligated to follow. +guildlines-line3=!!!No rights can be derived from these guidelines as the full list of rules (another tab in this window) is valid / operative!!! +guildlines-line4=- Hacking / cheating / abusing bugs will not be tolerated. +guildlines-line5=- Be polite and use common sense. +guildlines-line6=- Spamming (in the form of chat, bots, unlimited chests and concrete) is not allowed. +guildlines-line7=- Do not remove stuff without asking your fellow players. +guildlines-line8=- Trains are only allowed in LHD (Left Hand Drive). No train loops! +guildlines-line9= +guildlines-line10=If you have any questions about our rules, the server or Factorio in general, feel free to ask your fellow players or our helpful team. Have fun! +chat-name=How To Chat +chat-tooltip=How to chat in Factorio with default key config +chat-singleline=Chatting can be difficult for new players because it’s different than other games! It’s very simple, the button you need to press is the “GRAVE/TILDE” key (which is located under the “ESC key”) - If you would like to change the key, go to your Controls tab in options. The key you need to change is “Toggle LUA console” +commands-name=Commands +commands-tooltip=Commands that you can use in ExplosiveGaming +commands-singleline=Custom commands that you can use. Base commands are not shown here. +commands-col1=Command Name +commands-col2=Command Help +links-name=Links +links-tooltip=Helpful links for ways to get in touch with us +links-cap1=Discord voice and chat server: +links-cap2=Our website: +links-cap3=Steam: +links-cap4=Patreon: +links-cap5=Our wiki: +servers-name=Servers +servers-tooltip=Info on our other servers +servers-singleline=Welcome to the Explosive Gaming Community! S1-S3 are staggered resets. +servers-format=S__1__: __2__ +servers-cap1=Public +servers-des1=A place for all players, this map resets every 144H At 16:00 UTC. +servers-cap2=Public +servers-des2=A place for all players, this map resets every 144H At 16:00 UTC. +servers-cap3=Public +servers-des3=A place for all players, this map resets every 144H At 16:00 UTC. +servers-cap4=Modded +servers-des4=A Modded server for all players. Link on Discord for members. +servers-cap5=Events +servers-des5=Server for events (everyone can join) - May require a password. Join Discord for more info +servers-cap6=Donator +servers-des6=For players who support us financially. Changes can be made per request. +rules-name=Rules +rules-tooltip=The full list of ExplosiveGaming rules. +rules-singleline=Although the guidelines cover most of our rules, the full list always have more priority and override any guideline. It is advised to be familiar with all rules to prevent warnings or bans. +rules-format=__1__) __2__ +rules-rule1=Hacking / cheating / abusing bugs will not be tolerated. +rules-rule2=Any bugs or exploits found should be reported to our team members. (excluding creative items) +rules-rule3=Do not disrespect any player in the server. +rules-rule4=Taking all items from a belt or logistics request is forbidden: sharing resources is mandatory. +rules-rule5=Spamming (in the form of chat, bots, unlimited chests and concrete) is not allowed. +rules-rule6=Do not lay down/remove concrete or stone with bots without permission. +rules-rule7=Do not use active provider chests without permission. +rules-rule8=Do not use speakers on global or with alerts without permission. +rules-rule9=Do not remove/move major parts of the factory without permission. +rules-rule10=Do not walk in random directions for no reason (to save map size and server resources). +rules-rule11=Do not remove stuff without asking your fellow players. +rules-rule12=Do not rotate belts, deactivate belts with wires, or cause production to stop. +rules-rule13=Do not make train roundabouts. Or any loops of any kind. +rules-rule14=When using trains, use the same size other players have used. +rules-rule15=Trains are Left Hand Drive (LHD) only. +rules-rule16=Do not complain about lag, low fps and low ups etc. +rules-rule17=Do not ask for ranks. Our ranks are synchronized with Discord, make sure to join us there. +rules-rule18=Do not advertise other servers unless you are a trusted server owner. +rules-rule19=Report players who break the rules. +rules-rule20=Use common sense and what an Admin says goes. diff --git a/locale/en/ExpGamingInfo.Rockets.cfg b/locale/en/ExpGamingInfo.Rockets.cfg new file mode 100644 index 00000000..263d9b2c --- /dev/null +++ b/locale/en/ExpGamingInfo.Rockets.cfg @@ -0,0 +1,12 @@ +[ExpGamingInfo-Rockets] +name=Rocket Info +tooltip=List of details about the rockets sent. +none=No rockets have been sent yet. +nan=Not available +sent=Rockets Sent: __1__ +first=First Lanuched At: __1__ +last=Last Launch Took: __1__ +time=Average Launch Time: __1__ +fastest=Fastest Launch: __1__ +milestones=Milestones: +format=__1__: __2__ \ No newline at end of file diff --git a/locale/en/ExpGamingInfo.Science.cfg b/locale/en/ExpGamingInfo.Science.cfg new file mode 100644 index 00000000..a9bc1526 --- /dev/null +++ b/locale/en/ExpGamingInfo.Science.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Science Info +tooltip=List of details about science packs. +total=Packs Made: +time=Packs Per Minute: +format=__1__: __2__ +science-pack-1=Red +science-pack-2=Green +science-pack-3=Blue +military-science-pack=Military +production-science-pack=Production +high-tech-science-pack=High Tech +space-science-pack=Space +none=No science packs have been made yet. \ No newline at end of file diff --git a/locale/en/ExpGamingInfo.Tasklist.cfg b/locale/en/ExpGamingInfo.Tasklist.cfg new file mode 100644 index 00000000..7e698acf --- /dev/null +++ b/locale/en/ExpGamingInfo.Tasklist.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Task List +tooltip=Jobs that needs to be completed all around the factory. +none=There are currently no tasks. Ask a Member in-game or through Discord to add tasks. \ No newline at end of file diff --git a/locale/en/ExpGamingPlayer.inventorySearch.cfg b/locale/en/ExpGamingPlayer.inventorySearch.cfg new file mode 100644 index 00000000..0c45c5b1 --- /dev/null +++ b/locale/en/ExpGamingPlayer.inventorySearch.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Your inventory was searched and __1__ was removed. +med=Your inventory was searched and __1__ was removed, you have been given a warning as a result. +high=Your inventory was searched and __1__ was removed: this is NOT allowed. You have been temp-banned as a result. \ No newline at end of file diff --git a/locale/en/ExpGamingPlayer.playerInfo.cfg b/locale/en/ExpGamingPlayer.playerInfo.cfg new file mode 100644 index 00000000..4bbc1f12 --- /dev/null +++ b/locale/en/ExpGamingPlayer.playerInfo.cfg @@ -0,0 +1,9 @@ +[ExpGamingPlayer-playerInfo] +yes=Yes +no=No +name=[__1__] __2__ +online=Is Online: __1__ (__2__) +admin=Has Admin: __1__ +group=In User Group: __1__ +role=Highest Role: __1__ +roles=Other Roles: __1__ \ No newline at end of file diff --git a/locale/en/ExpGamingPlayer.playerList.cfg b/locale/en/ExpGamingPlayer.playerList.cfg new file mode 100644 index 00000000..d2c2e345 --- /dev/null +++ b/locale/en/ExpGamingPlayer.playerList.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Toggle player list, right click player for more info +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=No info file was found \ No newline at end of file diff --git a/locale/en/ExpGamingPlayer.polls.cfg b/locale/en/ExpGamingPlayer.polls.cfg new file mode 100644 index 00000000..afd15bf3 --- /dev/null +++ b/locale/en/ExpGamingPlayer.polls.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Polls +tooltip=View Old Polls +no-poll=No Old Polls +end=Poll Just Ended: __1__ +winner=__1__ had the most votes. +time-left=You will have __1__s to pick. \ No newline at end of file diff --git a/locale/en/GameSettingsGui.cfg b/locale/en/GameSettingsGui.cfg new file mode 100644 index 00000000..54825990 --- /dev/null +++ b/locale/en/GameSettingsGui.cfg @@ -0,0 +1,32 @@ +[GameSettingsGui] +name=Game Settings +tooltip=Edits Game Settings. Please use responsibly. +basic-name=Basic Settings +basic-tooltip=These settings are safe to edit and have no big impact. +basic-message=Basic Settings can be used to improve game play for players. +advanced-name=Advanced Settings +advanced-tooltip=These settings should be left alone unless you know what you are doing. +advanced-message=Please do not touch the Advanced Settings unless you are 100% sure what you are doing: changes made to these settings might have a bigger impact than you realise. +personal-name=Personal Settings +personal-tooltip=Personal Settings only affect you. +personal-message=Personal Settings only affect your character. If you are spotted as a result of these settings, you are on your own! +sure=Are you sure? +effect-mining-speed=Mining Speed +effect-craft-speed=Crafting Speed +effect-running-speed=Running Speed +effect-build-distance=Build Distance +effect-reach-distance=Reach Distance +effect-bot-speed=Bot Speed +effect-lab-speed=Lab Speed +effect-stack-bonus=Stack Bonus +effect-quickbar-count=Quickbar Count +effect-inventory-size=Inventory Size +effect-mining-prod=Mining Productivity +effect-game-speed=Game Speed +effect-save=Save Game +effect-reload-effects=Reload Effects +effect-reload-map=Reload Minimap +effect-kill-biters=Kill Biters +effect-crc=Force CRC Check +effect-reset-force=Reset Force +effect-clear-pollution=Clear Pollution \ No newline at end of file diff --git a/locale/en/GuiAnnouncements.cfg b/locale/en/GuiAnnouncements.cfg new file mode 100644 index 00000000..be1e94da --- /dev/null +++ b/locale/en/GuiAnnouncements.cfg @@ -0,0 +1,6 @@ +[GuiAnnouncements] +name=Announcements +tooltip=Sends an announcement to all players +sent-to=This announcement is sent to __1__ +sent-by=This announcement was sent by __1__ ( __2__ ) +select-rank=This announcement will be sent to: \ No newline at end of file diff --git a/locale/en/WarpPoints.cfg b/locale/en/WarpPoints.cfg new file mode 100644 index 00000000..0f517e6e --- /dev/null +++ b/locale/en/WarpPoints.cfg @@ -0,0 +1,10 @@ +[WarpPoints] +name=Warp List +tooltip=A list of warp points. +remove-tooltip=Remove Warp point +go-to-tooltip=Go To +cooldown=You must wait for the cooldown. Time left: __1__ +cooldown-zero=Your cooldown has expired, You can use warp points again. +name-used=That name is already taken. +too-close=You are too close to an existing warp point to make a new one. +not-on-warp=You are not on a warp point right now, you must be on a warp point to go to one. \ No newline at end of file diff --git a/locale/en/exp-core.cfg b/locale/en/exp-core.cfg deleted file mode 100644 index c5453d60..00000000 --- a/locale/en/exp-core.cfg +++ /dev/null @@ -1,22 +0,0 @@ -[commands] -unauthorized=401 - Unauthorized: Access is denied due to invalid credentials -invalid-inputs=Invalid Input, /__1__ __2__ -invalid-range=Invalid Range, Min: __1__, Max: __2__ -invalid-length=Invalid Length, Max: __1__ -invalid-player=Invaild Player Name, __1__ ,try using tab key to auto-complete the name -offline-player=Player is offline: Command failed to run -dead-player=Player is dead: Command failed to run -command-ran=Command Complete - -[ranking] -all-rank-print=[Everyone]: __1__ -rank-print=[__1__]: __2__ -rank-up=__1__ was promoted to __2__ by __3__ -rank-down=__1__ was demoted to __2__ by __3__ -rank-given=You have been given the __1__ Rank! -tag-reset=Your Tag was reset due to a Rank change - -[gui] -unauthorized=401 - Unauthorized: Access is denied due to invalid credentials -cant-open=You can't open this panel right now, reason: __1__ -cant-open-no-reason=You can't open this panel right now diff --git a/locale/fr/DeconControl.cfg b/locale/fr/DeconControl.cfg new file mode 100644 index 00000000..8eca4e13 --- /dev/null +++ b/locale/fr/DeconControl.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=You are not allowed to do this yet, You require the Regular rank, you must play for at least 3 hours +rank-print=__1__ tried to deconstruct something. \ No newline at end of file diff --git a/locale/fr/ExpGamingAdmin.AdminLib.cfg b/locale/fr/ExpGamingAdmin.AdminLib.cfg new file mode 100644 index 00000000..f882fc1c --- /dev/null +++ b/locale/fr/ExpGamingAdmin.AdminLib.cfg @@ -0,0 +1,15 @@ +[ExpGamingAdmin] +name=Commandes Admin +tooltip=Des commandes très puissantes résident ici. +no-info-file=Aucun fichier info trouvé +message=Veuillez sélectionner un joueur et une action, faites en sorte que ce soit la bonne ! +warning=Attention, ce joueur est de rang supérieur au vôtre, vous ne pouvez le modifier. +short-reason=Attention, la raison indiquée est trop courte. Soyez concis mais aussi précis. (Warning: The reason is too short. UPDATE) +rank-high=Ce joueur est de rang supérieur, veuillez utiliser une commande dont vous maîtriser l'utilisation ! +invalid=Le Joueur ou l'action est invalide, ré-essayez ! +take-action=Agir +tooltip-ban=Bannir un Joueur +tooltip-kick=Exclure un Joueur +tooltip-jail=Emprisonner un Joueur +tooltip-go-to=Aller à la position d'un Joueur +tooltip-bring=Amener le Joueur à soi diff --git a/locale/fr/ExpGamingAdmin.Warnings.cfg b/locale/fr/ExpGamingAdmin.Warnings.cfg new file mode 100644 index 00000000..c48f518a --- /dev/null +++ b/locale/fr/ExpGamingAdmin.Warnings.cfg @@ -0,0 +1,11 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=This Warnings Was Given By: __1__ +player-warning=__1__ was given a warning by __2__ reason: __3__ +temp-ban=__1__ was temp-ban by __2__ and will remain in jail untill next reset +remove-warn=You are had a warning Removed, you have __1__ warnings, next removed in __2__ +message=You Are Currently Reciving Warnings From The Script, This Will Continue Unless You Cease And Desist +reported=You Have Been Reported To The Admins By The Script, Further Acction May Be Taken If You Do Not Cease And Desist. +kick-warn=You Are On A Warning To Be KICKED, The Script Will Auto Kick If You Do Not Cease And Desist. +temp-warn=You Are On A Warning To Be TEMP BANNED, The Script Will Auto Ban If You Do Not Cease And Desist. +ban-warn=You Are On A Warning To Be BANNED, The Script Will Auto Ban If You Do Not Cease And Desist. +last-warn=YOU ARE ON A LAST WARNING TO BE BANNED, THE SCRIPT WILL AUTO BAN IF YOU DO NOT CEASE AND DESIST. \ No newline at end of file diff --git a/locale/fr/ExpGamingAdmin.cfg b/locale/fr/ExpGamingAdmin.cfg new file mode 100644 index 00000000..f882fc1c --- /dev/null +++ b/locale/fr/ExpGamingAdmin.cfg @@ -0,0 +1,15 @@ +[ExpGamingAdmin] +name=Commandes Admin +tooltip=Des commandes très puissantes résident ici. +no-info-file=Aucun fichier info trouvé +message=Veuillez sélectionner un joueur et une action, faites en sorte que ce soit la bonne ! +warning=Attention, ce joueur est de rang supérieur au vôtre, vous ne pouvez le modifier. +short-reason=Attention, la raison indiquée est trop courte. Soyez concis mais aussi précis. (Warning: The reason is too short. UPDATE) +rank-high=Ce joueur est de rang supérieur, veuillez utiliser une commande dont vous maîtriser l'utilisation ! +invalid=Le Joueur ou l'action est invalide, ré-essayez ! +take-action=Agir +tooltip-ban=Bannir un Joueur +tooltip-kick=Exclure un Joueur +tooltip-jail=Emprisonner un Joueur +tooltip-go-to=Aller à la position d'un Joueur +tooltip-bring=Amener le Joueur à soi diff --git a/locale/fr/ExpGamingBot.autoChat.cfg b/locale/fr/ExpGamingBot.autoChat.cfg new file mode 100644 index 00000000..32fea59f --- /dev/null +++ b/locale/fr/ExpGamingBot.autoChat.cfg @@ -0,0 +1,20 @@ +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=You cant use global chat commands +players-online=There are __1__ players online +players=There have been __1__ players on this map +map-time=This map has been on for __1__ +line-8=Type /help for more info +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) +not-real-dev=Cooldude2606 is a dev for this server and makes the softmod (look top left) and is not a factorio dev. +softmod=A softmod is a custom scenario that runs on this server, example is the player list. +blame=Blame __1__ for what just happend! +afk=Your afk? Look at __1__ they have been afk for: __2__ +links=To see links open the readme and click links. +magic=Fear the admin magic (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) \ No newline at end of file diff --git a/locale/fr/ExpGamingBot.autoMessage.cfg b/locale/fr/ExpGamingBot.autoMessage.cfg new file mode 100644 index 00000000..49d19ede --- /dev/null +++ b/locale/fr/ExpGamingBot.autoMessage.cfg @@ -0,0 +1,9 @@ +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=There are __1__ players online +map-time=This map has been on for __1__ +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) \ No newline at end of file diff --git a/locale/fr/ExpGamingCore.Command.cfg b/locale/fr/ExpGamingCore.Command.cfg new file mode 100644 index 00000000..5d271090 --- /dev/null +++ b/locale/fr/ExpGamingCore.Command.cfg @@ -0,0 +1,9 @@ +[ExpGamingCore_Command] +unauthorized=401 - Unauthorized: Access is denied due to invalid credentials +invalid-inputs=Invalid Input, /__1__ __2__ +invalid-range=Invalid Range, Min: __1__, Max: __2__ +invalid-length=Invalid Length, Max: __1__ +invalid-player=Invaild Player Name, __1__ ,try using tab key to auto-complete the name +offline-player=Player is offline, Command Failed To Run +dead-player=Player is dead, Command Failed To Run +command-ran=Command Complete \ No newline at end of file diff --git a/locale/fr/ExpGamingCore.Commands.cfg b/locale/fr/ExpGamingCore.Commands.cfg new file mode 100644 index 00000000..5d271090 --- /dev/null +++ b/locale/fr/ExpGamingCore.Commands.cfg @@ -0,0 +1,9 @@ +[ExpGamingCore_Command] +unauthorized=401 - Unauthorized: Access is denied due to invalid credentials +invalid-inputs=Invalid Input, /__1__ __2__ +invalid-range=Invalid Range, Min: __1__, Max: __2__ +invalid-length=Invalid Length, Max: __1__ +invalid-player=Invaild Player Name, __1__ ,try using tab key to auto-complete the name +offline-player=Player is offline, Command Failed To Run +dead-player=Player is dead, Command Failed To Run +command-ran=Command Complete \ No newline at end of file diff --git a/locale/fr/ExpGamingCore.Gui.cfg b/locale/fr/ExpGamingCore.Gui.cfg new file mode 100644 index 00000000..a8976a4e --- /dev/null +++ b/locale/fr/ExpGamingCore.Gui.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 - Unauthorized: Access is denied due to invalid credentials +cant-open=You can not open this panel right now, reason: __1__ +cant-open-no-reason=You can not open this panel right now \ No newline at end of file diff --git a/locale/fr/ExpGamingCore.Ranking.cfg b/locale/fr/ExpGamingCore.Ranking.cfg new file mode 100644 index 00000000..dc641783 --- /dev/null +++ b/locale/fr/ExpGamingCore.Ranking.cfg @@ -0,0 +1,7 @@ +[ranking] +all-rank-print=[Everyone]: __1__ +rank-print=[__1__]: __2__ +rank-up=__1__ was promoted to __2__ by __3__ +rank-down=__1__ was demoted to __2__ by __3__ +rank-given=You have been given the __1__ Rank! +tag-reset=Your Tag was reset due to a Rank change \ No newline at end of file diff --git a/locale/fr/ExpGamingInfo.Readme.cfg b/locale/fr/ExpGamingInfo.Readme.cfg new file mode 100644 index 00000000..45c6f9d0 --- /dev/null +++ b/locale/fr/ExpGamingInfo.Readme.cfg @@ -0,0 +1,68 @@ +[ExpGamingInfo-Readme] +tooltip=Open the readme gui that opens when you first join. +guildlines-name=Guild Lines +guildlines-tooltip=These are the guildlines you should follow +guildlines-line1=Welcome to the Explosive Gaming Community! +guildlines-line2= +guildlines-line3=Here are some guidelines to keep this Server fun for everyone: +guildlines-line4=- Hacking / cheating / abusing bugs will not be tolerated. +guildlines-line5=- Be polite and use common sense. +guildlines-line6=- Nobody likes spam. That includes: Chat, Bots, unlimited Chests and Concrete. +guildlines-line7=- Do not remove stuff without even trying to talk / ask about it. +guildlines-line8=- Trains: LHD (Left hand drive), no Loops and use them for long distances. (- Trains are only allowed in LHD (Left Hand Drive). Train loops. UPDATE) +guildlines-line9= +guildlines-line10=If you have any questions about the rules, the server or the game in general, feel free to ask. Have Fun! +chat-name=How To Chat +chat-tooltip=How to chat in factorio with default key config +chat-singleline=Chatting can be difficult for new players because it’s different than other games! It’s very simple, the button you need to press is the “GRAVE/TILDE” key it’s located under the “ESC key”. If you would like to change the key go to your controls tab in options. The key you need to change is “Toggle Lua console” it’s located in the second column 2nd from bottom. +commands-name=Commands +commands-tooltip=These are the commands you can use +commands-singleline=These are the many diffrent custom commands you are able to use, the base game commands are not shown +commands-col1=Command Name +commands-col2=Command Help +links-name=Links +links-tooltip=Helpful links for ways to get in touch +links-cap1=Discord voice and chat server: +links-cap2=Our website: +links-cap3=Steam: +links-cap4=Patreon: +servers-name=Servers +servers-tooltip=Info on our other servers +servers-singleline=Welcome to the Explosive Gaming Community! +servers-format=S__1__: __2__ +servers-cap1=Public +servers-des1=A place for all players, this map reset every 24h. +servers-cap2=Standard +servers-des2=Before you play make sure you understand the game, reset every 48h. +servers-cap3=Pro +servers-des3=A pure mega base server, reset every 7 days and a password is needed to join. +servers-cap4=Modded +servers-des4=A modded server not much to say, just download the mods to play. Link on Discord for members. +servers-cap5=Events +servers-des5=Sometimes we hold events, may require a password, join discord for more info. +servers-cap6=Donator +servers-des6=For those people who have two much money and give us some. Anything goes per request. +rules-name=All Rules +rules-tooltip=A full list of rules for the server +rules-singleline=This is a full list of rules what must be followed, the guildlines will cover most points in here but for those who like to follow the rules word to word then here is the full list. +rules-format=__1__) __2__ +rules-rule1=Hacking/cheating, exploiting and abusing bugs is not allowed. +rules-rule2=Any bugs or exploits found should be reported. (no creative items) +rules-rule3=Do not disrespect any player in the server. +rules-rule4=Do not take every item frmo a belt or via logics request, share resources. +rules-rule5=Do not spam, this includes stuff such as chat spam, item spam, chest spam etc. +rules-rule6=Do not laydown or remove concrete or stone with bots without permission. +rules-rule7=Do not use active provider chests without permission. +rules-rule8=Do not use speakers on global or with alearts without permission. +rules-rule9=Do not remove/move major parts of the factory without permission. +rules-rule10=Do not walk in player random direction for no reason(to save map size). +rules-rule11=Do not remove stuff just because you dont like it, tell people first. +rules-rule12=Do not rotate belts, deactive belts with wires, or cause production to stop. +rules-rule13=Do not make train roundabouts. Or any loops of any kind. +rules-rule14=When using trains use the same size that others have used. +rules-rule15=Trains are Left Hand Drive (LHD) only. +rules-rule16=Do not complain about lag, low fps and low ups or other things like that. +rules-rule17=Do not ask for rank, our ranks are synced with discord, admins cant give ranks. +rules-rule18=Do not advertise other servers unless you are a trusted server owner. +rules-rule19=Report any one who breaks the rules. +rules-rule20=Use common sense and what an admin says goes. \ No newline at end of file diff --git a/locale/fr/ExpGamingInfo.Rockets.cfg b/locale/fr/ExpGamingInfo.Rockets.cfg new file mode 100644 index 00000000..344c368d --- /dev/null +++ b/locale/fr/ExpGamingInfo.Rockets.cfg @@ -0,0 +1,12 @@ +[ExpGamingInfo-Rockets] +name=Rocket Info +tooltip=List of details about the rockets sent. +none=No rockets have been sent yet. +nan=NaN +sent=Rockets Sent: __1__ +first=First Lanuched At: __1__ +last=Last Launch Took: __1__ +time=Average Launch Time: __1__ +fastest=Fastest Launch: __1__ +milestones=Milestones: +format=__1__: __2__ \ No newline at end of file diff --git a/locale/fr/ExpGamingInfo.Science.cfg b/locale/fr/ExpGamingInfo.Science.cfg new file mode 100644 index 00000000..a9bc1526 --- /dev/null +++ b/locale/fr/ExpGamingInfo.Science.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Science Info +tooltip=List of details about science packs. +total=Packs Made: +time=Packs Per Minute: +format=__1__: __2__ +science-pack-1=Red +science-pack-2=Green +science-pack-3=Blue +military-science-pack=Military +production-science-pack=Production +high-tech-science-pack=High Tech +space-science-pack=Space +none=No science packs have been made yet. \ No newline at end of file diff --git a/locale/fr/ExpGamingInfo.Tasklist.cfg b/locale/fr/ExpGamingInfo.Tasklist.cfg new file mode 100644 index 00000000..e739ac38 --- /dev/null +++ b/locale/fr/ExpGamingInfo.Tasklist.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Task List +tooltip=What jobs need to be done round the factory. +none=There are no tasks to do right now, ask a member to add some. \ No newline at end of file diff --git a/locale/fr/ExpGamingPlayer.inventorySearch.cfg b/locale/fr/ExpGamingPlayer.inventorySearch.cfg new file mode 100644 index 00000000..4d3eb1e4 --- /dev/null +++ b/locale/fr/ExpGamingPlayer.inventorySearch.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Your Inventory Was Search And __1__ was removed. +med=Your Inventory Was Search And __1__ was removed, you have been given a warning. +high=Your Inventory Was Search And __1__ was found, this is not allowed AT ALL, your inventory has been moved to spawn. \ No newline at end of file diff --git a/locale/fr/ExpGamingPlayer.playerInfo.cfg b/locale/fr/ExpGamingPlayer.playerInfo.cfg new file mode 100644 index 00000000..257168f7 --- /dev/null +++ b/locale/fr/ExpGamingPlayer.playerInfo.cfg @@ -0,0 +1,8 @@ +[ExpGamingPlayer-playerInfo] +yes=Yes +no=No +name=[__1__] __2__ +online=Is Online: __1__ (__2__) +admin=Has Admin: __1__ +group=In User Group: __1__ +role=Has Rank: __1__ \ No newline at end of file diff --git a/locale/fr/ExpGamingPlayer.playerList.cfg b/locale/fr/ExpGamingPlayer.playerList.cfg new file mode 100644 index 00000000..83d2dd03 --- /dev/null +++ b/locale/fr/ExpGamingPlayer.playerList.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Toogle player list, right click player for info +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=No info file was found \ No newline at end of file diff --git a/locale/fr/ExpGamingPlayer.polls.cfg b/locale/fr/ExpGamingPlayer.polls.cfg new file mode 100644 index 00000000..afd15bf3 --- /dev/null +++ b/locale/fr/ExpGamingPlayer.polls.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Polls +tooltip=View Old Polls +no-poll=No Old Polls +end=Poll Just Ended: __1__ +winner=__1__ had the most votes. +time-left=You will have __1__s to pick. \ No newline at end of file diff --git a/locale/fr/GameSettingsGui.cfg b/locale/fr/GameSettingsGui.cfg new file mode 100644 index 00000000..f13485d0 --- /dev/null +++ b/locale/fr/GameSettingsGui.cfg @@ -0,0 +1,31 @@ +[GameSettingsGui] +name=Game Settings +tooltip=Allows for editing of the game settings, please use resposibliy. +basic-name=Basic Settings +basic-tooltip=These settings are safe to change with no large effects. +basic-message=These settings are force wide settings which can be used to inprove gameplay and make it more enjoyible for players. +advanced-name=Advanced Settings +advanced-tooltip=These settings should be left alone unless you know what you are doing. +advanced-message=Please do not touch these settings at all unless you know 100% what they do and the effect of using them, leave game.speed alone it has a bigger effect then you think. +personal-name=Personal Settings +personal-tooltip=These will only effect you, if you are spoted you are on your own. +personal-message=These settings will only effect your player any changes you make are to be resposible ones and dont over do it or you may be caught using them. +sure=Are You Sure! +effect-mining-speed=Mining Speed +effect-craft-speed=Crafting Speed +effect-running-speed=Running Speed +effect-build-distance=Build Distance +effect-reach-distance=Reach Distance +effect-bot-speed=Bot Speed +effect-lab-speed=Lab Speed +effect-stack-bonus=Stack Bonus +effect-quickbar-count=Quickbar Count +effect-inventory-size=Inventory Size +effect-mining-prod=Mining Productivity +effect-game-speed=Game Speed +effect-save=Save Game +effect-reload-effects=Reload Effects +effect-reload-map=Reload Minimap +effect-kill-biters=Kill Biters +effect-crc=Force CRC Check +effect-reset-force=Reset Force \ No newline at end of file diff --git a/locale/fr/GuiAnnouncements.cfg b/locale/fr/GuiAnnouncements.cfg new file mode 100644 index 00000000..11041b57 --- /dev/null +++ b/locale/fr/GuiAnnouncements.cfg @@ -0,0 +1,6 @@ +[GuiAnnouncements] +name=Announcement +tooltip=Sent an announcement to players +sent-to=This is sent to __1__ +sent-by=This was sent by __1__ of rank __2__ +select-rank=This message will be sent to: \ No newline at end of file diff --git a/locale/fr/WarpPoints.cfg b/locale/fr/WarpPoints.cfg new file mode 100644 index 00000000..b15a3345 --- /dev/null +++ b/locale/fr/WarpPoints.cfg @@ -0,0 +1,9 @@ +[WarpPoints] +name=Warp List +tooltip=A list of warp points. +remove-tooltip=Remove Warp Point +go-to-tooltip=Go To +cooldown=You Must Wait For The Cooldown, Time Left: __1__ +cooldown-zero=You Cooldown Has Expired, YOu Can Use Warp Points Again. +name-used=That Name Is Already Taken +not-on-warp=You Are Not On A Warp Point Right Now, You Must Be On A Warp Point To Go To One. \ No newline at end of file diff --git a/locale/nl/DeconControl.cfg b/locale/nl/DeconControl.cfg new file mode 100644 index 00000000..bc857511 --- /dev/null +++ b/locale/nl/DeconControl.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=Je moet minstens 3 uur gespeeld hebben om dit uit te voeren. +rank-print=__1__ heeft geprobeerd iets te deconstrueren. diff --git a/locale/nl/ExpGamingAdmin.AdminLib.cfg b/locale/nl/ExpGamingAdmin.AdminLib.cfg new file mode 100644 index 00000000..ff47947a --- /dev/null +++ b/locale/nl/ExpGamingAdmin.AdminLib.cfg @@ -0,0 +1,15 @@ +[ExpGamingAdmin] +name=Admin Commands +tooltip=Admin Commands kan je hier vinden. +no-info-file=Infobestand niet gevonden. +message=Selecteer een speler en de bijbehorende actie. Wees er zeker van dat je de correcte actie kiest. +warning=Fout: Je kan de rank van deze speler niet aanpassen omdat het jouw rank overtreft. +short-reason=Fout: De reden is te kort. (Warning: The reason is too short. UPDATE) +rank-high=Fout: Deze speler overtreft jouw rank. +invalid=Fout: De speler kan niet gevonden worden en/of de actie is onjuist. Probeer opnieuw! +take-action=Actie ondernemen +tooltip-ban=Ban speler +tooltip-kick=Kick speler +tooltip-jail=Jail speler +tooltip-go-to=Ga naar speler +tooltip-bring=Breng speler diff --git a/locale/nl/ExpGamingAdmin.Warnings.cfg b/locale/nl/ExpGamingAdmin.Warnings.cfg new file mode 100644 index 00000000..104ef981 --- /dev/null +++ b/locale/nl/ExpGamingAdmin.Warnings.cfg @@ -0,0 +1,11 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=Deze waarschuwing is gegeven door: __1__ +player-warning=__1__ is gewaarschuwd door __2__ met de reden: __3__ +temp-ban=__1__ is verbannen door __2__ en is gejailed tot de volgende reset. +remove-warn=Een waarschuwing is verlopen. Je hebt nu nog maar __1__ waarschuwing, volgende waarschuwing verloopt in __2__ +message=Je ontvangt waarschuwingen door het systeem. Deze waarschuwingen stoppen niet tot je stopt met wat je verkeerd doet. +reported=Je bent gerapporteerd aan de administrators door het systeem. Je zal bestraft worden als je niet stopt met wat je verkeerd doet. +kick-warn=WAARSCHUWING: Dit is je laatste waarschuwing voordat je gekickt wordt. +temp-warn=WAARSCHUWING: Dit is je laatste waarschuwing voordat je tijdelijk verbannen wordt. +ban-warn=WAARSCHUWING: Dit is je laatste waarschuwing voordat je permanent verbannen wordt. +last-warn=DIT IS JE LAATSTE WAARSCHUWING. Het systeem zal je automatisch VERBANNEN als je niet stopt met wat je verkeerd doet. diff --git a/locale/nl/ExpGamingAdmin.cfg b/locale/nl/ExpGamingAdmin.cfg new file mode 100644 index 00000000..ff47947a --- /dev/null +++ b/locale/nl/ExpGamingAdmin.cfg @@ -0,0 +1,15 @@ +[ExpGamingAdmin] +name=Admin Commands +tooltip=Admin Commands kan je hier vinden. +no-info-file=Infobestand niet gevonden. +message=Selecteer een speler en de bijbehorende actie. Wees er zeker van dat je de correcte actie kiest. +warning=Fout: Je kan de rank van deze speler niet aanpassen omdat het jouw rank overtreft. +short-reason=Fout: De reden is te kort. (Warning: The reason is too short. UPDATE) +rank-high=Fout: Deze speler overtreft jouw rank. +invalid=Fout: De speler kan niet gevonden worden en/of de actie is onjuist. Probeer opnieuw! +take-action=Actie ondernemen +tooltip-ban=Ban speler +tooltip-kick=Kick speler +tooltip-jail=Jail speler +tooltip-go-to=Ga naar speler +tooltip-bring=Breng speler diff --git a/locale/nl/ExpGamingBot.autoChat.cfg b/locale/nl/ExpGamingBot.autoChat.cfg new file mode 100644 index 00000000..32fea59f --- /dev/null +++ b/locale/nl/ExpGamingBot.autoChat.cfg @@ -0,0 +1,20 @@ +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=You cant use global chat commands +players-online=There are __1__ players online +players=There have been __1__ players on this map +map-time=This map has been on for __1__ +line-8=Type /help for more info +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) +not-real-dev=Cooldude2606 is a dev for this server and makes the softmod (look top left) and is not a factorio dev. +softmod=A softmod is a custom scenario that runs on this server, example is the player list. +blame=Blame __1__ for what just happend! +afk=Your afk? Look at __1__ they have been afk for: __2__ +links=To see links open the readme and click links. +magic=Fear the admin magic (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) \ No newline at end of file diff --git a/locale/nl/ExpGamingBot.autoMessage.cfg b/locale/nl/ExpGamingBot.autoMessage.cfg new file mode 100644 index 00000000..49d19ede --- /dev/null +++ b/locale/nl/ExpGamingBot.autoMessage.cfg @@ -0,0 +1,9 @@ +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=There are __1__ players online +map-time=This map has been on for __1__ +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) \ No newline at end of file diff --git a/locale/nl/ExpGamingCore.Command.cfg b/locale/nl/ExpGamingCore.Command.cfg new file mode 100644 index 00000000..3742ef49 --- /dev/null +++ b/locale/nl/ExpGamingCore.Command.cfg @@ -0,0 +1,9 @@ +[ExpGamingCore_Command] +unauthorized=401 - Onbevoegd: toegang wordt geweigerd vanwege ongeldige inloggegevens +invalid-inputs=Onjuiste invoer, /__1__ __2__ +invalid-range=Onjuiste radius, Min: __1__, Max: __2__ +invalid-length=Onjuiste lengte, Max: __1__ +invalid-player=Onjuiste naam, __1__ , probeer tab te gebruiken om de naam automatisch in te vullen +offline-player=Speler is offline. +dead-player=Speler is dood. +command-ran=Commando uitgevoerd. diff --git a/locale/nl/ExpGamingCore.Commands.cfg b/locale/nl/ExpGamingCore.Commands.cfg new file mode 100644 index 00000000..3742ef49 --- /dev/null +++ b/locale/nl/ExpGamingCore.Commands.cfg @@ -0,0 +1,9 @@ +[ExpGamingCore_Command] +unauthorized=401 - Onbevoegd: toegang wordt geweigerd vanwege ongeldige inloggegevens +invalid-inputs=Onjuiste invoer, /__1__ __2__ +invalid-range=Onjuiste radius, Min: __1__, Max: __2__ +invalid-length=Onjuiste lengte, Max: __1__ +invalid-player=Onjuiste naam, __1__ , probeer tab te gebruiken om de naam automatisch in te vullen +offline-player=Speler is offline. +dead-player=Speler is dood. +command-ran=Commando uitgevoerd. diff --git a/locale/nl/ExpGamingCore.Gui.cfg b/locale/nl/ExpGamingCore.Gui.cfg new file mode 100644 index 00000000..d53dc64c --- /dev/null +++ b/locale/nl/ExpGamingCore.Gui.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 - Onbevoegd: toegang wordt geweigerd vanwege ongeldige inloggegevens +cant-open=Je kan dit momenteel niet openen. Reden: __1__ +cant-open-no-reason=Je kan dit momenteel niet openen. \ No newline at end of file diff --git a/locale/nl/ExpGamingCore.Ranking.cfg b/locale/nl/ExpGamingCore.Ranking.cfg new file mode 100644 index 00000000..16e5c4f1 --- /dev/null +++ b/locale/nl/ExpGamingCore.Ranking.cfg @@ -0,0 +1,7 @@ +[ranking] +all-rank-print=[Everyone]: __1__ +rank-print=[__1__]: __2__ +rank-up=__1__ is gepromoot naar __2__ door __3__ +rank-down=__1__ is gedegradeerd naar __2__ door __3__ +rank-given=Je rank is veranderd naar __1__ +tag-reset=Je tag is gereset door een wijziging in je rank. \ No newline at end of file diff --git a/locale/nl/ExpGamingInfo.Readme.cfg b/locale/nl/ExpGamingInfo.Readme.cfg new file mode 100644 index 00000000..cc54dbd3 --- /dev/null +++ b/locale/nl/ExpGamingInfo.Readme.cfg @@ -0,0 +1,68 @@ +[ExpGamingInfo-Readme] +tooltip=Open de ReadMe wanneer je voor het eerst speelt. +guildlines-name=Richtlijnen +guildlines-tooltip=Dit zijn de richtlijnen die je moet volgen. +guildlines-line1=Welkom op de ExplosiveGaming community! +guildlines-line2= +guildlines-line3=Hier zijn een aantal richtlijnen die ieder speler moet volgen. +guildlines-line4=- Hacken / cheaten en bugs misbruiken is niet toegestaan. +guildlines-line5=- Wees aardig en gebruik je gezonde verstand. +guildlines-line6=- Spammen (in de zin van chat, kisten en beton) is niet toegestaan. +guildlines-line7=- Geen spullen verwijderen zonder toestemming van andere spelers. +guildlines-line8=- Treinen (LHD - Left Hand Drive) geen loops. (- Trains are only allowed in LHD (Left Hand Drive). Train loops. UPDATE) +guildlines-line9= +guildlines-line10=Als je vragen hebt over deze regels of over de server in algemeen, aarzel dan niet om contact op te nemen met onze staff. +chat-name=Chatten +chat-tooltip=Chatten in Factorio met standaard instellingen +chat-singleline=Chatten kan moeilijk zijn voor nieuwe spelers omdat de chatmechanisme in Factorio anders is dan andere spellen. Het is simpel: druk op de "GRAVE/TILDE" knop (locatie is onder de ESC knop). Als je deze knop wilt aanpassen, ga naar de Controls tab in Opties. De knop die je moet aanpassen is "Toggle LUA Console" +commands-name=Commands +commands-tooltip=Dit zijn de commands die je kunt gebruiken. +commands-singleline=Er zijn veel verschillende custom commands die je kunt gebruiken. Let er wel op dat basis commands hier niet zichtbaar zijn. +commands-col1=Commando naam +commands-col2=Commando hulp +links-name=Links +links-tooltip=Nuttige links om in contact te komen met de community +links-cap1=Discord server: +links-cap2=Onze website: +links-cap3=Steam: +links-cap4=Patreon: +servers-name=Servers +servers-tooltip=Info over onze andere servers +servers-singleline=Welkom op de ExplosiveGaming community! S1 tot en met S3 heeft geplande resets. +servers-format=S__1__: __2__ +servers-cap1=Openbaar +servers-des1=Server voor alle spelers, deze map reset elke 144 uur om 16:00 UTC. +servers-cap2=Openbaar +servers-des2=A place for all players, deze map reset elke 144 uur om 16:00 UTC. +servers-cap3=Openbaar +servers-des3=A place for all players, deze map reset elke 144 uur om 16:00 UTC. +servers-cap4=Modded +servers-des4=Een modded server voor alle spelers. Links zijn te vinden in de Discord server. +servers-cap5=Events +servers-des5=Server voor events. Links en wachtwoorden zijn te vinden in de Discord server. +servers-cap6=Donator +servers-des6=Voor de spelers die ons financieel ondersteunen. +rules-name=Alle regels +rules-tooltip=Een lijst met regels die van toepassing zijn op alle ExplosiveGaming servers. +rules-singleline=Dit is een lijst met alle regels. De richtlijnen behandelt de meeste punten, maar de volledige lijst is ook van toepassing. +rules-format=__1__) __2__ +rules-rule1=Hacken / cheaten en bugs misbruiken is niet toegestaan. +rules-rule2=Bugs of fouten horen gerapporteerd te worden aan de staff. +rules-rule3=Respecteer iedereen in de server. +rules-rule4=Pak niet alles uit een belt of via logistiekaanvragen: deel je middelen. +rules-rule5=Spammen (in de zin van chat, kisten en beton) is niet toegestaan. +rules-rule6=Bouw geen beton of steen met bots zonder toestemming. +rules-rule7=Gebruik geen actieve providerkist zonder toestemming. +rules-rule8=Gebruik geen speakers (globaal of met alerts) zonder toestemming. +rules-rule9=Verwijder geen grote delen van het fabriek zonder toestemming. +rules-rule10=Loop niet in willekeurige plekken zonder een reden (bespaart mapgrootte en server resources) +rules-rule11=Geen spullen verwijderen zonder toestemming van andere spelers. +rules-rule12=Draai de belts niet, deactiveer belts niet met draden en laat de productie niet stoppen. +rules-rule13=Maak geen treinrotondes of lussen. +rules-rule14=Gebruik de zelfde grootte treinen als andere spelers. +rules-rule15=Treinen zijn alleen LHD (Left Hand Drive) +rules-rule16=Klaag niet over de lag, lage FPS of lage UPS. +rules-rule17=Vraag niet om ranks: ranks zijn synchroon met onze Discord server. +rules-rule18=Maak geen reclame voor andere servers, tenzij je daarvoor bevoegd bent. +rules-rule19=Rapporteer spelers die de regels breken. +rules-rule20=Gebruik gezond verstand. diff --git a/locale/nl/ExpGamingInfo.Rockets.cfg b/locale/nl/ExpGamingInfo.Rockets.cfg new file mode 100644 index 00000000..2fee0a06 --- /dev/null +++ b/locale/nl/ExpGamingInfo.Rockets.cfg @@ -0,0 +1,12 @@ +[ExpGamingInfo-Rockets] +name=Raket Info +tooltip=Lijst met details over de verstuurde raketten. +none=Er zijn nog geen raketten verstuurd. +nan=Niet beschikbaar +sent=Raketten verstuurd: __1__ +first=Eerste raket gelanceerd op: __1__ +last=Meest recente lancering: __1__ +time=Gemiddelde lanceertijd: __1__ +fastest=Snelste lancering: __1__ +milestones=Mijlpalen: +format=__1__: __2__ diff --git a/locale/nl/ExpGamingInfo.Science.cfg b/locale/nl/ExpGamingInfo.Science.cfg new file mode 100644 index 00000000..2ac8d7c0 --- /dev/null +++ b/locale/nl/ExpGamingInfo.Science.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Wetenschap info +tooltip=Lijst met details over de wetenschaps pakketten. +total=Pakketten gemaakt: +time=Pakketten per minuut: +format=__1__: __2__ +science-pack-1=Rood +science-pack-2=Groen +science-pack-3=Blauw +military-science-pack=Militair +production-science-pack=Productie +high-tech-science-pack=High Tech +space-science-pack=Ruimte +none=Er zijn nog geen wetenschaps pakketten gemaakt. diff --git a/locale/nl/ExpGamingInfo.Tasklist.cfg b/locale/nl/ExpGamingInfo.Tasklist.cfg new file mode 100644 index 00000000..6ab37662 --- /dev/null +++ b/locale/nl/ExpGamingInfo.Tasklist.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Taaklijst +tooltip=Wat voor werk er rondom de fabriek gedaan moet worden +none=Er zijn momenteel geen taken. Vraag een Member om taken toe te voegen. diff --git a/locale/nl/ExpGamingPlayer.inventorySearch.cfg b/locale/nl/ExpGamingPlayer.inventorySearch.cfg new file mode 100644 index 00000000..2c6b6a60 --- /dev/null +++ b/locale/nl/ExpGamingPlayer.inventorySearch.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Je inventaris is doorzocht en __1__ is verwijderd. +med=Je inventaris is doorzocht en __1__ is verwijderd, je bent gewaarschuwd. +high=Je inventaris is doorzocht en __1__ is gevonden, dit is ten strengste verboden! Je inventaris is verwijderd. diff --git a/locale/nl/ExpGamingPlayer.playerInfo.cfg b/locale/nl/ExpGamingPlayer.playerInfo.cfg new file mode 100644 index 00000000..931736ee --- /dev/null +++ b/locale/nl/ExpGamingPlayer.playerInfo.cfg @@ -0,0 +1,8 @@ +[ExpGamingPlayer-playerInfo] +yes=Ja +no=Nee +name=[__1__] __2__ +online=Is Online: __1__ (__2__) +admin=Heeft Admin: __1__ +group=In Groep: __1__ +role=Heeft Rank: __1__ diff --git a/locale/nl/ExpGamingPlayer.playerList.cfg b/locale/nl/ExpGamingPlayer.playerList.cfg new file mode 100644 index 00000000..6a58e08a --- /dev/null +++ b/locale/nl/ExpGamingPlayer.playerList.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Toggle speler lijst. Rechtermuisklik op een speler voor meer info +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=Geen infobestand gevonden. diff --git a/locale/nl/ExpGamingPlayer.polls.cfg b/locale/nl/ExpGamingPlayer.polls.cfg new file mode 100644 index 00000000..928ddefb --- /dev/null +++ b/locale/nl/ExpGamingPlayer.polls.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Polls +tooltip=Laat oude polls zien +no-poll=Geen oude polls +end=Poll is zojuist beëindigd: __1__ +winner=__1__ had de meeste stemmen. +time-left=Je hebt __1__s om te kiezen. diff --git a/locale/nl/GameSettingsGui.cfg b/locale/nl/GameSettingsGui.cfg new file mode 100644 index 00000000..19017a6b --- /dev/null +++ b/locale/nl/GameSettingsGui.cfg @@ -0,0 +1,31 @@ +[GameSettingsGui] +name=Game instellingen +tooltip=Maakt het mogelijk om gameinstellingen te wijzigen. Gebruik het verantwoord! +basic-name=Basis instellingen +basic-tooltip=Deze instellingen kunnen veilig worden gewijzigd. +basic-message=Deze instellingen kunnen worden gebruikt om het spelervaring voor de spelers te verbeteren. +advanced-name=Geavanceerde instellingen +advanced-tooltip=Het is ten zeerste aangeraden om niet aan deze instellingen te zitten, tenzij je weet wat je doet. +advanced-message=Waarschuwing: Niet aan deze instellingen zitten tenzij je honderd procent zeker weet wat je aan het doen bent. Het wijzigen van deze instellingen kunnen een groter effect hebben dan je denkt. +personal-name=Persoonlijke instellingen +personal-tooltip=Deze instellingen hebben alleen effect op jouw speler. +personal-message=Deze instellingen hebben alleen effect op jouw speler: gebruik het verantwoord, aangezien het overmatig gebruik van deze instellingen niet zijn toegestaan. +sure=Weet je het zeker? +effect-mining-speed=Mining Snelheid +effect-craft-speed=Crafting Snelheid +effect-running-speed=Ren Snelheid +effect-build-distance=Bouwafstand +effect-reach-distance=Bereik +effect-bot-speed=Bot Snelheid +effect-lab-speed=Lab Snelheid +effect-stack-bonus=Stack Bonus +effect-quickbar-count=Quickbar Count +effect-inventory-size=Inventory grootte +effect-mining-prod=Mining Productiviteit +effect-game-speed=Gamesnelheid +effect-save=Opslaan +effect-reload-effects=Effecten herladen +effect-reload-map=Minimap herladen +effect-kill-biters=Biters vermoorden +effect-crc=Forceer CRC check +effect-reset-force=Forceren resetten diff --git a/locale/nl/GuiAnnouncements.cfg b/locale/nl/GuiAnnouncements.cfg new file mode 100644 index 00000000..5c92cc68 --- /dev/null +++ b/locale/nl/GuiAnnouncements.cfg @@ -0,0 +1,6 @@ +[GuiAnnouncements] +name=Mededelingen +tooltip=Verstuurt een mededeling naar iedereen +sent-to=Deze mededeling is gestuurd naar __1__ +sent-by=Deze mededeling is gestuurd door __1__ ( __2__ ) +select-rank=Deze mededeling wordt gestuurd naar: diff --git a/locale/nl/WarpPoints.cfg b/locale/nl/WarpPoints.cfg new file mode 100644 index 00000000..b15a3345 --- /dev/null +++ b/locale/nl/WarpPoints.cfg @@ -0,0 +1,9 @@ +[WarpPoints] +name=Warp List +tooltip=A list of warp points. +remove-tooltip=Remove Warp Point +go-to-tooltip=Go To +cooldown=You Must Wait For The Cooldown, Time Left: __1__ +cooldown-zero=You Cooldown Has Expired, YOu Can Use Warp Points Again. +name-used=That Name Is Already Taken +not-on-warp=You Are Not On A Warp Point Right Now, You Must Be On A Warp Point To Go To One. \ No newline at end of file diff --git a/locale/sv-SE/DeconControl.cfg b/locale/sv-SE/DeconControl.cfg new file mode 100644 index 00000000..c8ad5cb7 --- /dev/null +++ b/locale/sv-SE/DeconControl.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=Du har inte tillåtelse med det här just nu. Du behöver ha rang "Regular" vilket kan uppnås genom 3 timmar inne i spelet (den här kartan) hos Explosive Gaming. +rank-print=__1__ försökte dekonstruera något. diff --git a/locale/sv-SE/ExpGamingAdmin.AdminLib.cfg b/locale/sv-SE/ExpGamingAdmin.AdminLib.cfg new file mode 100644 index 00000000..679188c2 --- /dev/null +++ b/locale/sv-SE/ExpGamingAdmin.AdminLib.cfg @@ -0,0 +1,19 @@ +[ExpGamingAdmin] +name=Adminkommandon +tooltip=Adminkommando gör dit hem här +no-info-file=Ingen informationsfil kunde hittas +message=Var snäll och välj en spelare och en åtgärd att utfärda, se till att du väljer den rätta! +warning=Warning: Den här spelaren har högre rang än dig. Därför kan du inte redigera dess rang. +short-reason=Warning: Skälet är för kort. +rank-high=Warning: Den här spelaren har högre rang än dig. Därför kan du inte redigera dess rang. +invalid=Spelaren eller åtgärden är ogiltig. Var vänlig och försök igen! +take-action=Utför åtgärd. +tooltip-ban=Bannlys Spelare +tooltip-kick=Sparka Spelare +tooltip-jail=Fängsla Spelare +tooltip-go-to=Gå till Spelare +tooltip-bring=Hämta spelare +report=Rapportera Spelare +low-print=__1__ har blivit rapporterad av __2__ för: __3__ +high-print=__1__ har blivit rapporterad av __2__ för: __3__ +cant-report=Den här spelaren kan inte bli rapporterad. diff --git a/locale/sv-SE/ExpGamingAdmin.Warnings.cfg b/locale/sv-SE/ExpGamingAdmin.Warnings.cfg new file mode 100644 index 00000000..9358b9cf --- /dev/null +++ b/locale/sv-SE/ExpGamingAdmin.Warnings.cfg @@ -0,0 +1,10 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=Den här varningen gavs av: __1__ +player-warning=__1__ var tillfälligt bannlyst av __2__ och kommer att förbli i fängelset tills nästa återställning (reset) +remove-warn=En av dina varningar har gått ut. Du har __1__ varning kvar, nästa varning kommer at tas bort om __2__ +message=Du får för nuvarande varningar av systemet. De kommer fortsätta tills du upphör med överträdelsen. +reported= Du har blivit rapporterad till administrationen av systemet. Mer påföljd kan komma att tas om du inte upphör med överträdelsen. +kick-warn=Det här är din sista varning innan du blir sparkad. Systemet kommer att automatisk sparka dig om du inte upphör med överträdelsen +temp-warn=Det här är din sista varning innan du blir tillfälligt bannlyst. Systemet kommer att automatiskt bannlysa dig om du inte upphör överträdelsen +ban-warn=VARNING: Det här är din sista varning innan du blir bannlyst. Systemet kommer att automatisk bannlysa dig om du inte upphör med överträdelsen. +last-warn=VARNING: Det här är din sista varning innan du blir permanent bannlyst. Systemet kommer att automatiskt permanent bannlysa dig om du inte upphör med överträdelsen. diff --git a/locale/sv-SE/ExpGamingAdmin.cfg b/locale/sv-SE/ExpGamingAdmin.cfg new file mode 100644 index 00000000..679188c2 --- /dev/null +++ b/locale/sv-SE/ExpGamingAdmin.cfg @@ -0,0 +1,19 @@ +[ExpGamingAdmin] +name=Adminkommandon +tooltip=Adminkommando gör dit hem här +no-info-file=Ingen informationsfil kunde hittas +message=Var snäll och välj en spelare och en åtgärd att utfärda, se till att du väljer den rätta! +warning=Warning: Den här spelaren har högre rang än dig. Därför kan du inte redigera dess rang. +short-reason=Warning: Skälet är för kort. +rank-high=Warning: Den här spelaren har högre rang än dig. Därför kan du inte redigera dess rang. +invalid=Spelaren eller åtgärden är ogiltig. Var vänlig och försök igen! +take-action=Utför åtgärd. +tooltip-ban=Bannlys Spelare +tooltip-kick=Sparka Spelare +tooltip-jail=Fängsla Spelare +tooltip-go-to=Gå till Spelare +tooltip-bring=Hämta spelare +report=Rapportera Spelare +low-print=__1__ har blivit rapporterad av __2__ för: __3__ +high-print=__1__ har blivit rapporterad av __2__ för: __3__ +cant-report=Den här spelaren kan inte bli rapporterad. diff --git a/locale/sv-SE/ExpGamingBot.autoChat.cfg b/locale/sv-SE/ExpGamingBot.autoChat.cfg new file mode 100644 index 00000000..98f81ad7 --- /dev/null +++ b/locale/sv-SE/ExpGamingBot.autoChat.cfg @@ -0,0 +1,25 @@ + +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=Du kan inte utföra globala chat-kommandon. +players-online=Det är __1__ spelare online +players=Det har varit __1__ spelare på den här kartan +map-time=Den här kartan har varit igång under __1__ +line-8=Type /help för mer information +join-us=Var snäll och förena dig med oss: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=Vi använder oss av specialiserade kommandon, som till exempel /tag och /report, se kommandotabben i readme för mer information. +read-readme=Se till att du har läst "Readme" (Finn den genom att klicka på frågetecknet högst upp i vänstra hörnet) +not-real-dev=Cooldude2606 är dev för den här servern och gör mjukmodden ("the softmod") och är inte en factorio dev. +ssoftmod=En mjukmod ("softmod") är ett specialscenario som används på den här servern, exempelvis listan över spelare. +blame=Skyll på __1__ för vad som just hände! +afk=Är du afk (borta från tangentbordet)? Titta på __1__, den spelaren har varit afk under: __2__ +links=För att se länkar, öppna readme och klicka "länkar". +magic=Frukta admin-magin (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) +loops=INGA LOOPAR; LOOPAR ÄR DÅLIGT; JUST INGA LOOPAR!!!!!; OM DU GJÖR EN LOOP.... DET KOMMER INTE ATT SLUTA VÄL!!!!!!! +lhd=Alla tåg skall köras med vänstertrafik! +current-evolution=Nuvarande evolutionsfaktor är __1__ +wiki=Du kan få mer information om oss och scenariot på vår wiki: https://wiki.explosivegaming.nl/ \ No newline at end of file diff --git a/locale/sv-SE/ExpGamingBot.autoMessage.cfg b/locale/sv-SE/ExpGamingBot.autoMessage.cfg new file mode 100644 index 00000000..f037d9df --- /dev/null +++ b/locale/sv-SE/ExpGamingBot.autoMessage.cfg @@ -0,0 +1,10 @@ + +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=Det är __1__ spelare online +map-time=Den här kartan har varit igång under __1__ +join-us=Var snäll och förena dig med oss: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=Vi använder oss av specialiserade kommandon, som till exempel /tag och /report, se kommandotabben i readme för mer information. +read-readme=Se till att du har läst "Readme" (Finn den genom att klicka på frågetecknet högst upp i vänstra hörnet) \ No newline at end of file diff --git a/locale/sv-SE/ExpGamingCore.Command.cfg b/locale/sv-SE/ExpGamingCore.Command.cfg new file mode 100644 index 00000000..5ee344f0 --- /dev/null +++ b/locale/sv-SE/ExpGamingCore.Command.cfg @@ -0,0 +1,9 @@ +[ExpGamingCore_Command] +unauthorized=401 - Otillåten: Tillgång nekas på grund av otillräcklig säkerhetsprövning. +invalid-inputs=Igiltig inmatning, /__1__ __2__ +invalid-range=Invalid räckvid, Min: __1__, Max: __2__ +invalid-length=ogiltig längd, Max: __1__ +invalid-player=Ogiltigt spelarnamn, __1__ , försök använda tab-tangenten för att auto-slutföra namn. +offline-player=Spelare är offline. Kommando misslyckades med att köras. +dead-player=Spelare är död. Kommando misslyckades med att köras. +command-ran=Kommandot slutfört diff --git a/locale/sv-SE/ExpGamingCore.Commands.cfg b/locale/sv-SE/ExpGamingCore.Commands.cfg new file mode 100644 index 00000000..5ee344f0 --- /dev/null +++ b/locale/sv-SE/ExpGamingCore.Commands.cfg @@ -0,0 +1,9 @@ +[ExpGamingCore_Command] +unauthorized=401 - Otillåten: Tillgång nekas på grund av otillräcklig säkerhetsprövning. +invalid-inputs=Igiltig inmatning, /__1__ __2__ +invalid-range=Invalid räckvid, Min: __1__, Max: __2__ +invalid-length=ogiltig längd, Max: __1__ +invalid-player=Ogiltigt spelarnamn, __1__ , försök använda tab-tangenten för att auto-slutföra namn. +offline-player=Spelare är offline. Kommando misslyckades med att köras. +dead-player=Spelare är död. Kommando misslyckades med att köras. +command-ran=Kommandot slutfört diff --git a/locale/sv-SE/ExpGamingCore.Gui.cfg b/locale/sv-SE/ExpGamingCore.Gui.cfg new file mode 100644 index 00000000..279ba842 --- /dev/null +++ b/locale/sv-SE/ExpGamingCore.Gui.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 -Otillåten: Tillgång nekas på grund av otillräcklig säkerhetsprövning. +cant-open=Du kan inte öppna den här panelen just nu, orsak: __1__ +cant-open-no-reason=Du kan inte öppna den här panelen just nu \ No newline at end of file diff --git a/locale/sv-SE/ExpGamingCore.Ranking.cfg b/locale/sv-SE/ExpGamingCore.Ranking.cfg new file mode 100644 index 00000000..8ee4d10a --- /dev/null +++ b/locale/sv-SE/ExpGamingCore.Ranking.cfg @@ -0,0 +1,7 @@ +[ranking] +all-rank-print=[Everyone]: __1__ +rank-print=[__1__]: __2__ +rank-up=__1__ blev befordrad till __2__ av __3__ +rank-down=__1__ blev degraderad till __2__ av __3__ +rank-given=Du har fått __1__ Rang! +tag-reset=Din tag blev återställd på grund av rangförändrning. \ No newline at end of file diff --git a/locale/sv-SE/ExpGamingInfo.Readme.cfg b/locale/sv-SE/ExpGamingInfo.Readme.cfg new file mode 100644 index 00000000..5299c304 --- /dev/null +++ b/locale/sv-SE/ExpGamingInfo.Readme.cfg @@ -0,0 +1,69 @@ +[ExpGamingInfo-Readme] +tooltip=Öppna ReadMe om det här är första gången du ansluter dig. +guildlines-name=Riktlinjer +guildlines-tooltip=Det här är riktlinjerna som alla bör följa +guildlines-line1=Välkommen till gemenskapen ExplosiveGaming! +guildlines-line2=Här är riktlinjerna som alla är tvingade att följa. +guildlines-line3=!!!No rights can be derived from these guidelines as the full list of rules (another tab in this window) is valid / operative!!! +guildlines-line4=- Dataintrång / fusk / missbruk av buggar kommer inte att tolereras. +guildlines-line5=- Var artig och använd sunt förnuft. +guildlines-line6=- Spam (genom chat, bottar, obegränsade kistor och betong) är inte tillåtet. +guildlines-line7=- Ta inte bort saker utan att fråga dina medspelare. +guildlines-line8=- Tåg är bara tillåtna med vänstertrafik. Inga tågloopar! +guildlines-line9= +guildlines-line10= Om du har frågor om reglerna, servern eller generelt om Factorio, känn dig fri att fråga dina medspelare eller vårat hjälpsamma team. Ha kul! +chat-name=Hur du chattar +chat-tooltip=Hur du chattar i Factorio med standardinställningar +chat-singleline=Att chatta kan vara svårt för nya spelare efterson det är annurlunda från andra spel. Det är väldigt enkelt, tangenten som du behöver trycka på är "ö".Om du vill byta det, gå in till "kontroller" och ändra tangent för "lua konsol". +commands-name=Kommandon +commands-tooltip=Kommandon som du kan använda i ExplosiveGaming +commands-singleline=Anpassade kommandon som du kan använda. Baskommandon visas inte här. +commands-col1=Kommandonamn +commands-col2=kommandohjälp +links-name=Länkar +links-tooltip=Hjälpfulla länkar som visar vägar att komma i kontakt med oss. +links-cap1=Discord röst- och chatserver: +links-cap2=Våran Webbadress : +links-cap3=Steam: +links-cap4=Patreon: +links-cap5=Vår wiki: +servers-name=Servrar +servers-tooltip=Information om våra servrar +servers-singleline=Välkommen till ExplosiveGamings gemenskap! S1-S3 har förskjutna återställningar (resets). +servers-format=S__1__: __2__ +servers-cap1=Offentlig +servers-des1=En plats för alla spelare, then här kartan återställs varje 144H, 16:00 UTC. +servers-cap2=Offentlig +servers-des2=En plats för alla spelare, then här kartan återställs varje 144H, 16:00 UTC. +servers-cap3=Offentlig +servers-des3=En plats för alla spelare, then här kartan återställs varje 144H, 16:00 UTC. +servers-cap4=Modifierad +servers-des4=En modifierad server för alla spelare. Länk i Discord för medlemmar. +servers-cap5=Evenemang +servers-des5=Server för evenemang (alla kan ansluta sig) - Kan kräva lösenord. Anslut dig till Discord för mer info. +servers-cap6=Donator +servers-des6=För spelare som stöder oss finansiellt. Ändringar kan göras på begäran. +rules-name=Regler +rules-tooltip=Den fullla listan över ExplosiveGamings regler. +rules-singleline=Även om riktlinjerna täcker de flesta av reglerna så har den fulla listan alltid prioritet och går alltid före riktlinjerna. Det är välbetänkt att vara bekant med alla reglerna för att förhindra varningar och bannlystningar. +rules-format=__1__) __2__ +rules-rule1=Dataintrång / fusk / missbruk av buggar kommer inte att tolereras. +rules-rule2=Buggar och utnyttjingssätt ska rapporteras till team-medlemmar (exkludera kreativa saker) +rules-rule3=Var inte respektlös mot någon annan spelare i servern. +rules-rule4=Att ta alla saker från ett bälte eller logistikbegäran är förbjudet: att dela med sig av resurserna är obligatoriskt. +rules-rule5=Spam (genom chat, bottar, obegränsade kistor eller betong) är inte tillåtet. +rules-rule6=Gör inga placeringar/borttagningar av betong eller sten med hjälp av bottar utan tillåtelse. +rules-rule7=Använd inte aktiva tillgångskistor utan tillåtelse. +rules-rule8=Använd inte globala högtalare eller varningar utan tillåtelse. +rules-rule9=Ta inte bort eller flytta huvuddelar av fabriken utan tillåtelse. +rules-rule10=Gå inte omkring i slumpvisa riktningar utan anledning (för att spara kartstorlek och serverresurser) +rules-rule11=Ta inte bort saker utan att fråga dina medspelare. +rules-rule12=Rotera inte bälten, deaktivera inte bälten med kabel och orsaka inte produktionsstop. +rules-rule13=Gör inte tågrondeller. Eller någon loop av något slag. +rules-rule14=Vid användning av tåg, använd samma storlek som andra spelare använt sig av. +rules-rule15=Tåg körs endast med vänstertrafik. +rules-rule16=Klaga inte om lag, låg fps, låg ups etc. +rules-rule17=Be inte om högre rang. Våra ranger är synkroniserade med Discord, se till att du ansluter dig till oss där. +rules-rule18=Gör inte reklam för andra servrar om du inte är en betrodd serverägare. +rules-rule19=Rapportera spelare som bryter mot reglerna. +rules-rule20=Använd sunt förnuft och vad en admin säger gäller. diff --git a/locale/sv-SE/ExpGamingInfo.Rockets.cfg b/locale/sv-SE/ExpGamingInfo.Rockets.cfg new file mode 100644 index 00000000..eb4d93bd --- /dev/null +++ b/locale/sv-SE/ExpGamingInfo.Rockets.cfg @@ -0,0 +1,13 @@ + +[ExpGamingInfo-Rockets] +name=Raketinformation +tooltip=Lista över detaljerna kring skickade raketer. +none=Inga raketer har blivit skickade ännu. +nan=Inte tillgängligt +sent=Skickade raketer: __1__ +first=Första uppskjutningen skedde: __1__ +last=Senaste uppskjutningen tog: __1__ +time=Genomsnittlig uppskjutningstid: __1__ +fastest=Snabbaste uppskjutning: __1__ +milestones=Milstolpar: +format=__1__: __2__ diff --git a/locale/sv-SE/ExpGamingInfo.Science.cfg b/locale/sv-SE/ExpGamingInfo.Science.cfg new file mode 100644 index 00000000..db40737c --- /dev/null +++ b/locale/sv-SE/ExpGamingInfo.Science.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Vetenskapsinformation +tooltip=Detaljerad lista över vetenskapspaket. +total=Paket gjorda: +time=Paket per minut: +format=__1__: __2__ +science-pack-1=Röda +science-pack-2=Gröna +science-pack-3=Blåa +military-science-pack=Militära +production-science-pack=Produktion +high-tech-science-pack=Högteknologiska +space-science-pack=Rymd +none=Inga vetenskapspaket har blivit gjorda ännu. diff --git a/locale/sv-SE/ExpGamingInfo.Tasklist.cfg b/locale/sv-SE/ExpGamingInfo.Tasklist.cfg new file mode 100644 index 00000000..5b0009bf --- /dev/null +++ b/locale/sv-SE/ExpGamingInfo.Tasklist.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Uppgiftslista +tooltip=Jobb som behövs slutföras överallt i fabriken +none=Det finns för närvarande inga uppgifter. Fråga en medlem i spelet eller via Discord för att lägga till nya uppgifter. \ No newline at end of file diff --git a/locale/sv-SE/ExpGamingPlayer.inventorySearch.cfg b/locale/sv-SE/ExpGamingPlayer.inventorySearch.cfg new file mode 100644 index 00000000..ff5995b3 --- /dev/null +++ b/locale/sv-SE/ExpGamingPlayer.inventorySearch.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Ditt inventarie blev genomsökt och __1__ togs bort. +med=Ditt inventarie blev genomsökt och __1__ togs bort, du har fått en varning på grund av detta. +high=Ditt inventarie blev genomsökt och __1__ togs bort: Det här är inte tillåtet. Som ett resultat av det har du blivit tillfälligt bannlyst. diff --git a/locale/sv-SE/ExpGamingPlayer.playerInfo.cfg b/locale/sv-SE/ExpGamingPlayer.playerInfo.cfg new file mode 100644 index 00000000..5a4406ae --- /dev/null +++ b/locale/sv-SE/ExpGamingPlayer.playerInfo.cfg @@ -0,0 +1,8 @@ +[ExpGamingPlayer-playerInfo] +yes=Ja +no=Nej +name=[__1__] __2__ +online=Är Online: __1__ (__2__) +admin=Har Admin: __1__ +group=I användargrupp: __1__ +role=Har rang: __1__ diff --git a/locale/sv-SE/ExpGamingPlayer.playerList.cfg b/locale/sv-SE/ExpGamingPlayer.playerList.cfg new file mode 100644 index 00000000..b871c389 --- /dev/null +++ b/locale/sv-SE/ExpGamingPlayer.playerList.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Växla spelarlista, högerklicka på spelare för mer information. +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=Ingen informationsfil kunde hittas diff --git a/locale/sv-SE/ExpGamingPlayer.polls.cfg b/locale/sv-SE/ExpGamingPlayer.polls.cfg new file mode 100644 index 00000000..e9050a52 --- /dev/null +++ b/locale/sv-SE/ExpGamingPlayer.polls.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Undersökningar +tooltip=Se gamla undersökningar +no-poll=Inga gamla undersökningar +end=Röstning slutade nyss: __1__ +winner=__1__ hade flest röster. +time-left=Du kommer att få __1__s på dig att välja. \ No newline at end of file diff --git a/locale/sv-SE/GameSettingsGui.cfg b/locale/sv-SE/GameSettingsGui.cfg new file mode 100644 index 00000000..88185c07 --- /dev/null +++ b/locale/sv-SE/GameSettingsGui.cfg @@ -0,0 +1,31 @@ +[GameSettingsGui] +name=Game Settings +tooltip=Edits Game Settings. Please use responsibly. +basic-name=Basic Settings +basic-tooltip=These settings are safe to edit and have no big impact. +basic-message=Basic Settings can be used to improve game play for players. +advanced-name=Advanced Settings +advanced-tooltip=These settings should be left alone unless you know what you are doing. +advanced-message=Please do not touch the Advanced Settings unless you are 100% sure what you are doing: changes made to these settings might have a bigger impact than you realize. +personal-name=Personal Settings +personal-tooltip=Personal Settings only affects you. +personal-message=Personal Settings only affects your character. If you are spotted as a result of these settings, you are on your own! +sure=Are you sure? +effect-mining-speed=Mining Speed +effect-craft-speed=Crafting Speed +effect-running-speed=Running Speed +effect-build-distance=Build Distance +effect-reach-distance=Reach Distance +effect-bot-speed=Bot Speed +effect-lab-speed=Lab Speed +effect-stack-bonus=Stack Bonus +effect-quickbar-count=Quickbar Count +effect-inventory-size=Inventory Size +effect-mining-prod=Mining Productivity +effect-game-speed=Game Speed +effect-save=Save Game +effect-reload-effects=Reload Effects +effect-reload-map=Reload Minimap +effect-kill-biters=Kill Biters +effect-crc=Force CRC Check +effect-reset-force=Reset Force diff --git a/locale/sv-SE/GuiAnnouncements.cfg b/locale/sv-SE/GuiAnnouncements.cfg new file mode 100644 index 00000000..2b3a8317 --- /dev/null +++ b/locale/sv-SE/GuiAnnouncements.cfg @@ -0,0 +1,7 @@ + +[GuiAnnouncements] +name=Meddelanden +tooltip=Sänder ett meddelande till alla spelare +sent-to=Det här meddelandet är skickat till __1__ +sent-by=Det här meddelandet är skickat av __1__ ( __2__ ) +select-rank=Det här meddelandet kommer att skickas till: diff --git a/locale/sv-SE/WarpPoints.cfg b/locale/sv-SE/WarpPoints.cfg new file mode 100644 index 00000000..afbdb799 --- /dev/null +++ b/locale/sv-SE/WarpPoints.cfg @@ -0,0 +1,9 @@ +[WarpPoints] +name=Warp-lista +tooltip=En lista över Warp-punkter. +remove-tooltip=Ta bort Warp-punkt +go-to-tooltip=Gå till +cooldown=Du måste vänta på nedräkningen. Tid kvar: __1__ +cooldown-zero=Din nedräkningstimer har gått ut, så nu kan du använda Warp-punkter igen. +name-used=Det namnet är redan taget. +not-on-warp=Du är inte på en Warp-punkt just nu, för att gå till en Warp-punkt måste du befinna dig på en. diff --git a/modules/AdvancedStartingItems/control.lua b/modules/AdvancedStartingItems/control.lua new file mode 100644 index 00000000..31c1e718 --- /dev/null +++ b/modules/AdvancedStartingItems/control.lua @@ -0,0 +1,45 @@ +--- Adds a better method of player starting items based on production levels. +-- @module AdvancedStartingItems@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Local Variables +local items = { + ['iron-plate']=function(player,made) if tick_to_min(game.tick) < 5 then return 8 else return (made*10)/math.pow(tick_to_min(game.tick),2) end end, + ['copper-plate']=function(player,made) if tick_to_min(game.tick) < 5 then return 0 else return (made*8)/math.pow(tick_to_min(game.tick),2) end end, + ['electronic-circuit']=function(player,made) if tick_to_min(game.tick) < 5 then return 0 else return (made*6)/math.pow(tick_to_min(game.tick),2) end end, + ['iron-gear-wheel']=function(player,made) if tick_to_min(game.tick) < 5 then return 0 else return (made*6)/math.pow(tick_to_min(game.tick),2) end end, + ['steel-plate']=function(player,made) if tick_to_min(game.tick) < 5 then return 0 else return(made*4)/math.pow(tick_to_min(game.tick),2) end end, + ['pistol']=function(player,made) if player.force.item_production_statistics.get_input_count('submachine-gun') > 5 then return 0 else return 1 end end, + ['submachine-gun']=function(player,made) if made > 5 then return 1 else return 0 end end, + ['firearm-magazine']=function(player,made) if player.force.item_production_statistics.get_input_count('piercing-rounds-magazine') > 100 then return 0 else return 10 end end, + ['piercing-rounds-magazine']=function(player,made) if made > 100 then return 10 else return 0 end end, + ['light-armor']=function(player,made) if made > 5 and player.force.item_production_statistics.get_input_count('heavy-armor') <= 5 then return 1 else return 0 end end, + ['heavy-armor']=function(player,made) if made > 5 then return 1 else return 0 end end, + ['burner-mining-drill']=function(player,made) if tick_to_min(game.tick) < 5 then return 4 else return 0 end end, + ['stone-furnace']=function(player,made) if tick_to_min(game.tick) < 5 then return 4 else return 0 end end, + ['iron-axe']=function(player,made) if made > 5 and player.force.item_production_statistics.get_input_count('steel-axe') <= 5 then return 1 else return 0 end end, + ['steel-axe']=function(player,made) if made > 5 then return 1 else return 0 end end +} + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Event Handlers Define +script.on_event(defines.events.on_player_created, function(event) + local player = game.players[event.player_index] + if event.player_index == 1 then + player.force.friendly_fire = false + game.map_settings.enemy_expansion.enabled = false + player.force.chart(player.surface, {{player.position.x - 400, player.position.y - 400}, {player.position.x + 400, player.position.y + 400}}) + end + for item,count in pairs(items) do + if type(count) == 'function' then count = math.floor(count(player,player.force.item_production_statistics.get_input_count(item))) end + if count > 0 then player.insert{name=item, count=count} end + end +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/AdvancedStartingItems/softmod.json b/modules/AdvancedStartingItems/softmod.json new file mode 100644 index 00000000..dc9653e1 --- /dev/null +++ b/modules/AdvancedStartingItems/softmod.json @@ -0,0 +1,20 @@ +{ + "name": "AdvancedStartingItems", + "version": "4.0.0", + "description": "Adds a better method of player starting items based on production levels.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Inventory", + "Start", + "Items", + "Player", + "Advanced", + "Useful", + "Balaced" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": {}, + "submodules": {} +} diff --git a/modules/ChatPopup/control.lua b/modules/ChatPopup/control.lua new file mode 100644 index 00000000..c22c1564 --- /dev/null +++ b/modules/ChatPopup/control.lua @@ -0,0 +1,56 @@ +--- Creates flying text above player when they send a message. +-- @module ChatPopup@4.0.0 +-- @author badgamernl +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ChatPopup + +-- Module Require +local Game = require('FactorioStdLib.Game') +local Color = require('FactorioStdLib.Color') + +local ChatPopup = {} + +function ChatPopup.sendFlyingText(player, text) + local _player = Game.get_player(player) + if not _player then return end + -- Split long text in chunks + local chunkSize = 40 + local chunks = {} + for i=1, #text, chunkSize do + chunks[#chunks+1] = text:sub(i,i+chunkSize - 1) + end + -- Iterate over text chunks and create them as floating text centered above the player + -- Disabled false centering because of not being able to disable scaling: (1 / 7.9 * #value) + for i,value in ipairs(chunks) do + _player.surface.create_entity{ + name="flying-text", + color=_player.chat_color, + text=value, + position={_player.position.x, _player.position.y-(2 - (1 * i))} + } + end +end + +script.on_event(defines.events.on_console_chat, function(event) + local player = game.players[event.player_index] + if not player then return end + if not event.message then return end + + -- Send message player send to player itself + local message = player.name .. ': ' .. event.message + ChatPopup.sendFlyingText(player, message) + + -- parse message for players and if it includes player, send him a notification that he has been mentioned in the chat + local player_message = event.message:lower():gsub("%s+", "") + + for i,_player in ipairs(game.connected_players) do + if _player.index ~= player.index then + if player_message:match(_player.name:lower()) then + ChatPopup.sendFlyingText(_player, 'You\'ve been mentioned by: ' ..player.name .. ' in chat!') + end + end + end + +end) + +return ChatPopup \ No newline at end of file diff --git a/modules/ChatPopup/softmod.json b/modules/ChatPopup/softmod.json new file mode 100644 index 00000000..273ab7d9 --- /dev/null +++ b/modules/ChatPopup/softmod.json @@ -0,0 +1,21 @@ +{ + "name": "ChatPopup", + "version": "4.0.0", + "description": "Creates flying text above player when they send a message.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Chat", + "Popup", + "Mention", + "Floating", + "Text" + ], + "author": "badgamernl", + "contact": "badgamernl@gmail.com", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Color": "^0.8.0" + }, + "submodules": {} +} diff --git a/modules/DamagePopup/control.lua b/modules/DamagePopup/control.lua new file mode 100644 index 00000000..b75b2003 --- /dev/null +++ b/modules/DamagePopup/control.lua @@ -0,0 +1,45 @@ +--- When a entity is damaged y a player it will show how much damage you've death, When a player gets attacked by a entity it will popup the player's health in color. +-- @module DamagePopup@4.0.0 +-- @author badgamernl +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias DamagePopup + +-- Module Require +local Color = require('FactorioStdLib.Color') + +local DamagePopup = {} + +script.on_event(defines.events.on_entity_damaged, function(event) + local entity = event.entity + local cause = event.cause + local damage = event.original_damage_amount + local health = entity.health + -- local pre_attack_health = health + damage -- Didn't use it after all, maybe useful later + + local color = defines.textcolor.crit + + if entity.name == 'player' then + if health > 100 then + if health > 200 then + color = defines.textcolor.low + else + color = defines.textcolor.med + end + end + entity.surface.create_entity{ + name="flying-text", + color=color, + text=math.floor(health), + position=entity.position + } + elseif cause and cause.name == 'player' then + entity.surface.create_entity{ + name="flying-text", + color=defines.textcolor.med, + text='-'..math.floor(damage), -- cooldude2606 added floor for damage amount + position=entity.position + } + end +end) + +return DamagePopup \ No newline at end of file diff --git a/modules/DamagePopup/softmod.json b/modules/DamagePopup/softmod.json new file mode 100644 index 00000000..a5ea4de0 --- /dev/null +++ b/modules/DamagePopup/softmod.json @@ -0,0 +1,19 @@ +{ + "name": "DamagePopup", + "version": "4.0.0", + "description": "When a entibty is damaged y a player it will show how much damage you've dealth, When a player gets attacked by a entity it will popup the player's health in color.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Damage", + "Popup", + "Floating", + "Text" + ], + "author": "badgamernl", + "contact": "badgamernl@gmail.com", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "FactorioStdLib.Color": "^0.8.0" + }, + "submodules": {} +} diff --git a/modules/DeathMarkers/control.lua b/modules/DeathMarkers/control.lua new file mode 100644 index 00000000..051e5eb3 --- /dev/null +++ b/modules/DeathMarkers/control.lua @@ -0,0 +1,45 @@ +--- Adds markers to the map when a player dies and removes it when the body is removed. +-- @module DeathMarkers@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Global Define +local global = global{ + corpses={} +} + +-- Event Handlers Define +script.on_event(defines.events.on_player_died, function(event) + local player = game.players[event.player_index] + local tag = player.force.add_chart_tag(player.surface,{ + position=player.position, + text='Death: '..player.name..' ('..tick_to_display_format(event.tick)..')' + }) + if not global.corpses then global.corpses = {} end + table.insert(global.corpses,tag) +end) + +script.on_event(defines.events.on_tick, function(event) + if (game.tick%3600) ~= 0 then return end + if not global.corpses then global.corpses = {} end + local key = 1 + while key <= #global.corpses do + local tag = global.corpses[key] + if not tag or not tag.valid then table.remove(global.corpses,key) else + if not tag.target then + local entity = tag.surface.find_entity('character-corpse',tag.position) + if entity then tag.target = entity + else tag.destroy() table.remove(global.corpses,key) key=key-1 end + elseif not tag.target.valid then tag.destroy() table.remove(global.corpses,key) key=key-1 end + end + key=key+1 + end +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/DeathMarkers/softmod.json b/modules/DeathMarkers/softmod.json new file mode 100644 index 00000000..ac58f593 --- /dev/null +++ b/modules/DeathMarkers/softmod.json @@ -0,0 +1,17 @@ +{ + "name": "DeathMarkers", + "version": "4.0.0", + "description": "Adds markers to the map when a player dies and removes it when the body is removed.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Death", + "Marker", + "Body", + "Map" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": {}, + "submodules": {} +} diff --git a/modules/DeconControl/control.lua b/modules/DeconControl/control.lua new file mode 100644 index 00000000..2976cb33 --- /dev/null +++ b/modules/DeconControl/control.lua @@ -0,0 +1,72 @@ +--- Allows control over decon rights, if ExpGamingCore.Role is not installed it will allow admins to instant remove trees and thats it. +-- @module DeconControl@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Game = require('FactorioStdLib.Game') +local Server = require('ExpGamingCore.Server') +local Role -- ExpGamingCore.Role@^4.0.0 +local Admin -- ExpGamingAdmin@^4.0.0 + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + if loaded_modules['ExpGamingAdmin'] then Admin = require('ExpGamingAdmin') end + end +} + +-- Event Handlers Define +Event.register(-1,function(event) + Server.new_thread{ + name='tree-decon', + data={trees={},cache={},clear=0} + }:on_event('tick',function(self) + local trees = self.data.trees + if self.data.clear ~= 0 and self.data.clear < game.tick then self.data.cache = {} self.data.clear = 0 end + if #trees == 0 then return end + for i = 0,math.ceil(#trees/10) do + local tree = table.remove(trees,1) + if tree and tree.valid then tree.destroy() end + end + end):on_event(defines.events.on_marked_for_deconstruction,function(self,event) + local cache = self.data.cache[event.player_index] + if not cache then + local player = Game.get_player(event) + if not player then return end + if not Role then + if player.admin then self.data.cache[event.player_index] = {'tree-decon',false} + else self.data.cache[event.player_index] = {'decon',false} end + else + if Role.allowed(player,'tree-decon') then self.data.cache[event.player_index] = {'tree-decon',false} + elseif not Role.allowed(player,'decon') then self.data.cache[event.player_index] = {'no-decon',false} + else self.data.cache[event.player_index] = {'decon',false} end + end + cache = self.data.cache[event.player_index] + end + if not event.entity.last_user or event.entity.name == 'entity-ghost' then + if cache[1] == 'tree-decon' then + table.insert(self.data.trees,event.entity) + self.data.clear = game.tick + 10 + end + else + if cache[1] == 'no-decon' then + event.entity.cancel_deconstruction('player') + if not cache[2] then + cache[2] = true + local player = Game.get_player(event) + player_return({'DeconControl.player-print'},defines.textcolor.crit,player) + Role.print(Role.meta.groups.Admin.lowest,{'DeconControl.rank-print',player.name},defines.textcolor.info) + if Admin then Admin.give_warning(player,'','Trying To Decon The Base') end + end + self.data.clear = game.tick + 10 + end + end + end):open() +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/DeconControl/locale/de.cfg b/modules/DeconControl/locale/de.cfg new file mode 100644 index 00000000..efab5765 --- /dev/null +++ b/modules/DeconControl/locale/de.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=Du darfst dies noch nicht entfernen. Du benötigst dazu den Rang Regular, den du nach 3 Stunden auf dem Server automatisch erhältst. +rank-print=__1__ versuchte etwas zu entfernen. \ No newline at end of file diff --git a/modules/DeconControl/locale/en.cfg b/modules/DeconControl/locale/en.cfg new file mode 100644 index 00000000..556c1f3a --- /dev/null +++ b/modules/DeconControl/locale/en.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=You do not have permission to do this right now. You require the Regular rank which can be obtained through 3 hours of in-game playtime on a server. +rank-print=__1__ tried to deconstruct something. diff --git a/modules/DeconControl/locale/fr.cfg b/modules/DeconControl/locale/fr.cfg new file mode 100644 index 00000000..8eca4e13 --- /dev/null +++ b/modules/DeconControl/locale/fr.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=You are not allowed to do this yet, You require the Regular rank, you must play for at least 3 hours +rank-print=__1__ tried to deconstruct something. \ No newline at end of file diff --git a/modules/DeconControl/locale/nl.cfg b/modules/DeconControl/locale/nl.cfg new file mode 100644 index 00000000..bc857511 --- /dev/null +++ b/modules/DeconControl/locale/nl.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=Je moet minstens 3 uur gespeeld hebben om dit uit te voeren. +rank-print=__1__ heeft geprobeerd iets te deconstrueren. diff --git a/modules/DeconControl/locale/sv-SE.cfg b/modules/DeconControl/locale/sv-SE.cfg new file mode 100644 index 00000000..c8ad5cb7 --- /dev/null +++ b/modules/DeconControl/locale/sv-SE.cfg @@ -0,0 +1,3 @@ +[DeconControl] +player-print=Du har inte tillåtelse med det här just nu. Du behöver ha rang "Regular" vilket kan uppnås genom 3 timmar inne i spelet (den här kartan) hos Explosive Gaming. +rank-print=__1__ försökte dekonstruera något. diff --git a/modules/DeconControl/softmod.json b/modules/DeconControl/softmod.json new file mode 100644 index 00000000..2f33a047 --- /dev/null +++ b/modules/DeconControl/softmod.json @@ -0,0 +1,26 @@ +{ + "name": "DeconControl", + "version": "4.0.0", + "description": "Allows control over decon rights, if ExpGamingCore.Role is not installed it will allow admins to instant remove trees and thats it.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Trees", + "Decon", + "Protection", + "Admin", + "Tool", + "Report" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "ExpGamingCore.Server": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingLib": "^4.0.0", + "ExpGamingAdmin.Warnings": "?^4.0.0", + "ExpGamingCore.Role": "?^4.0.0", + "ExpGamingAdmin": "?^4.0.0" + }, + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/Ban/control.lua b/modules/ExpGamingAdmin/Ban/control.lua new file mode 100644 index 00000000..0a5f1935 --- /dev/null +++ b/modules/ExpGamingAdmin/Ban/control.lua @@ -0,0 +1,49 @@ +--- Adds a custom ban function to the admin command set. +-- @module ExpGamingAdmin.Ban@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Admin = require('ExpGamingAdmin') +local AdminGui = require('ExpGamingAdmin.Gui') +local Server = require('ExpGamingCore.Server') +local Game = require('FactorioStdLib.Game') +local Color -- FactorioStdLib.Color@^0.8.0 +local Sync -- ExpGamingCore.Sync@^4.0.0 + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Sync'] then Sync = require('ExpGamingCore.Sync') end + if loaded_modules['FactorioStdLib.Color'] then Color = require('FactorioStdLib.Color') end + end +} + +-- Function Define +AdminGui.add_button('Ban','utility/danger_icon',{'ExpGamingAdmin.tooltip-ban'},function(player,byPlayer) + Admin.open(byPlayer,player,'Ban') +end) + +function Admin.ban(player,by_player,reason) + player = Game.get_player(player) + local by_player_name = Game.get_player(by_player) and Game.get_player(by_player).name or '' + reason = Admin.create_reason(reason,by_player_name) + Admin.set_banned(player,true) + if Sync then Sync.emit_embedded{ + title='Player Ban', + color=Color.to_hex(defines.textcolor.crit), + description='There was a player banned.', + ['Player:']='<>'..player.name, + ['By:']='<>'..by_player_name, + ['Reason:']=reason + } end + if Admin.move_inventory then Admin.move_inventory(player) end + Server.interface(game.ban_player,true,player,reason) +end + +Admin.add_action('Ban',Admin.ban) + +-- Module Return +return setmetatable(ThisModule,{__call=Admin.ban}) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Ban/softmod.json b/modules/ExpGamingAdmin/Ban/softmod.json new file mode 100644 index 00000000..a055b3e5 --- /dev/null +++ b/modules/ExpGamingAdmin/Ban/softmod.json @@ -0,0 +1,23 @@ +{ + "name": "ExpGamingAdmin.Ban", + "version": "4.0.0", + "description": "Adds a custom ban function to the admin command set.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Ban", + "Admin", + "Set", + "ExpGaming" + ], + "dependencies": { + "ExpGamingAdmin.Gui": "^4.0.0", + "ExpGamingCore.Server": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Color": "?^0.8.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingAdmin.ClearInventory": "?^4.0.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/ClearInventory/control.lua b/modules/ExpGamingAdmin/ClearInventory/control.lua new file mode 100644 index 00000000..dea36113 --- /dev/null +++ b/modules/ExpGamingAdmin/ClearInventory/control.lua @@ -0,0 +1,58 @@ +--- Adds a function to clear a players inventory and move the items to spawn. +-- @module ExpGamingAdmin.ClearInventory@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Admin = require('ExpGamingAdmin') +local Game = require('FactorioStdLib.Game') + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Function Define +local inventories = { + defines.inventory.player_main, + defines.inventory.player_quickbar, + defines.inventory.player_trash, + defines.inventory.player_guns, + defines.inventory.player_ammo, + defines.inventory.player_armor +} + +function Admin.move_item_to_spawn(item,surface,chests) + chests = chests or surface.find_entities_filtered{area={{-10,-10},{10,10}},name='iron-chest'} or {} + local chest = nil + while not chest or not chest.get_inventory(defines.inventory.chest).can_insert(item) do + chest = table.remove(chests,1) + if not chest then chest = surface.create_entity{ + name='iron-chest', + position=surface.find_non_colliding_position('iron-chest',{0,0},32,1) + } end + end + chest.get_inventory(defines.inventory.chest).insert(item) + table.insert(chests,chest) + return chests +end + +function Admin.move_inventory(player) + player = Game.get_player(player) + if not player then return end + local chests = player.surface.find_entities_filtered{area={{-10,-10},{10,10}},name='iron-chest'} or {} + for _,_inventory in pairs(inventories) do + local inventory = player.get_inventory(_inventory) + if inventory then + for item,count in pairs(inventory.get_contents()) do + item = {name=item,count=count} + chests = Admin.move_item_to_spawn(item,player.surface,chests) + end + inventory.clear() + end + end +end + +Admin.add_action('Clear Inventory',Admin.move_inventory) +-- Module Return +return setmetatable(ThisModule,{__call=Admin.move_inventory}) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/ClearInventory/softmod.json b/modules/ExpGamingAdmin/ClearInventory/softmod.json new file mode 100644 index 00000000..ae931353 --- /dev/null +++ b/modules/ExpGamingAdmin/ClearInventory/softmod.json @@ -0,0 +1,20 @@ +{ + "name": "ExpGamingAdmin.ClearInventory", + "version": "4.0.0", + "description": "Adds a function to clear a players inventoy and move the items to spawn.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Spawn", + "Items", + "Admin", + "Move", + "Clear", + "Inventory" + ], + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/Commands/control.lua b/modules/ExpGamingAdmin/Commands/control.lua new file mode 100644 index 00000000..73038cd6 --- /dev/null +++ b/modules/ExpGamingAdmin/Commands/control.lua @@ -0,0 +1,25 @@ +--- A full ranking system for factorio. +-- @module ExpGamingAdmin.Commands@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Admin = require('ExpGamingAdmin') + +--- Used to clear all parts of a player, removing warnings, reports, jail and temp ban +-- @command clear-all +-- @param player the player to clear +commands.add_command('clear-all', 'Clears a player of any temp-ban, reports or warnings', { + ['player']={true,'player'} +}, function(event,args) + Admin.clear_player(args.player,event.player_index) +end) + +return { + on_init = function(self) + if loaded_modules['ExpGamingAdmin.TempBan'] then verbose('ExpGamingAdmin.TempBan is installed; Loading tempban src') require(module_path..'/src/tempban',{self=Admin}) end + if loaded_modules['ExpGamingAdmin.Jail'] then verbose('ExpGamingAdmin.Jail is installed; Loading tempban src') require(module_path..'/src/jail',{self=Admin}) end + if loaded_modules['ExpGamingAdmin.Warnings'] then verbose('ExpGamingAdmin.Warnings is installed; Loading tempban src') require(module_path..'/src/warnings',{self=Admin}) end + if loaded_modules['ExpGamingAdmin.Reports'] then verbose('ExpGamingAdmin.Reports is installed; Loading tempban src') require(module_path..'/src/reports',{self=Admin}) end + if loaded_modules['ExpGamingAdmin.ClearInventory'] then verbose('ExpGamingAdmin.ClearInventory is installed; Loading tempban src') require(module_path..'/src/clear',{self=Admin}) end + end +} \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Commands/softmod.json b/modules/ExpGamingAdmin/Commands/softmod.json new file mode 100644 index 00000000..541a7255 --- /dev/null +++ b/modules/ExpGamingAdmin/Commands/softmod.json @@ -0,0 +1,29 @@ +{ + "name": "ExpGamingAdmin.Commands", + "version": "4.0.0", + "description": "Admins many of the admin featues which the script can use as in game commands.", + "location": "FSM_ARCHIVE", + "keywords": [ + "ExpGaming", + "Admin", + "Tools", + "Commands", + "Temp ban", + "Jail", + "Clear Inventory", + "Report", + "Warnings" + ], + "dependencies": { + "ExpGamingLib": "^4.0.0", + "ExpGamingCore.Command": "^4.0.0", + "ExpGamingAdmin.TempBan": "?^4.0.0", + "ExpGamingAdmin.Jail": "?^4.0.0", + "ExpGamingAdmin.Warnings": "?^4.0.0", + "ExpGamingAdmin.Reports": "?^4.0.0", + "ExpGamingAdmin.ClearInventory": "?^4.0.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/Commands/src/clear.lua b/modules/ExpGamingAdmin/Commands/src/clear.lua new file mode 100644 index 00000000..ec6262a7 --- /dev/null +++ b/modules/ExpGamingAdmin/Commands/src/clear.lua @@ -0,0 +1,12 @@ +local Admin = self + +--- Clears a players inventory and moves it to chests in spawn +-- @command clear-inv +-- @param player the player to clear the inventory of +commands.add_command('clear-inv', 'Clears a player\'s invetory', { + ['player'] = {true,'player-rank'} +}, function(event,args) + local player = args.player + if Admin.is_banned(player) then player_return({'ExpGamingAdmin.cant-report-ban',args.player.name}) return commands.error end + Admin.move_inventory(player) +end) diff --git a/modules/ExpGamingAdmin/Commands/src/jail.lua b/modules/ExpGamingAdmin/Commands/src/jail.lua new file mode 100644 index 00000000..7d60da06 --- /dev/null +++ b/modules/ExpGamingAdmin/Commands/src/jail.lua @@ -0,0 +1,30 @@ +local Admin = self +local Role = require('ExpGamingCore.Role') +local Server = require('ExpGamingCore.Server') + +--- Used to jail a player which stops them from moving +-- @command jail +-- @param player the player to be jailed +-- @param[opt] reason the reason the player was jailed +commands.add_command('jail', 'Jails a player', { + ['player']={true,'player-rank'}, + ['reason']={false,'string-inf'} +}, function(event,args) + local player = args.player + local reason = args.reason + if Role.has_flag(player,'not_reportable') then player_return{'ExpGamingAdmin.cant-report',args.player.name} return commands.error end + if Admin.is_banned(player) then player_return{'ExpGamingAdmin.cant-report-ban',args.player.name} return commands.error end + Admin.jail(player,event.player_index,reason) +end) + +--- Used to unjail a player +-- @command unjail +-- @param player the player to unjail +commands.add_command('unjail', 'Returns a player\'s old rank', { + ['player']={true,'player'} +}, function(event,args) + local player = args.player + if Admin.is_banned(player,true) ~= 'jail' then player_return({'ExpGamingAdmin.cant-report-ban',args.player.name}) return commands.error end + Admin.set_banned(player,false) + Server.interface(Role.revert,true,player,event.player_index,2) +end) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Commands/src/reports.lua b/modules/ExpGamingAdmin/Commands/src/reports.lua new file mode 100644 index 00000000..be67e7d8 --- /dev/null +++ b/modules/ExpGamingAdmin/Commands/src/reports.lua @@ -0,0 +1,35 @@ +local Admin = self +local Role = require('ExpGamingCore.Role') +local Game = require('FactorioStdLib.Game') + +--- Reports a player +-- @command report +-- @param player the player to report +-- @param[opt] reason the reason why the player was reported +commands.add_command('report', 'Reports a player', { + ['player']={true,'player-rank'}, + ['reason']={false,'string-inf'} +}, function(event,args) + local _player = Game.get_player(event) + local player = args.player + local reason = args.reason + if Admin.is_banned(player) then player_return({'ExpGamingAdmin.cant-report-ban',args.player.name}) return commands.error end + if Role.has_flag(player,'not_reportable') then player_return({'ExpGamingAdmin.cant-report',args.player.name}) return commands.error end + for _,report in pairs(global.addons.reports.reports) do if report[1] == _player.name then player_return({'ExpGamingAdmin.cant-report',args.player.name}) return commands.error end end + for _,report in pairs(global.addons.reports.verified) do if report[1] == _player.name then player_return({'ExpGamingAdmin.cant-report',args.player.name}) return commands.error end end + Admin.report(player,event.player_index,reason) +end) + +--- Clears the reports of the player +-- @command clear-reports +-- @param player the player to clear the reports of +commands.add_command('clear-reports', 'Clears a player\'s reports', { + ['player'] = {true,function(value) + local player,err = commands.validate['player'](value) + if err then return commands.error(err) end + local rtn = not Admin.is_banned(player) and player + if not rtn then return commands.error{'ExpGamingAdmin.cant-report-ban',value} end return rtn + end} +}, function(event,args) + Admin.clear_reports(args.player,event.player_index) +end) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Commands/src/tempban.lua b/modules/ExpGamingAdmin/Commands/src/tempban.lua new file mode 100644 index 00000000..8657d1ad --- /dev/null +++ b/modules/ExpGamingAdmin/Commands/src/tempban.lua @@ -0,0 +1,15 @@ +local Admin = self + +--- Used to temp ban a player and give a reason +-- @command temp-ban +-- @param player the player to temp ban +-- @param[opt] reason the reason for the ban +commands.add_command('temp-ban', 'Temporarily ban a player', { + ['player']={true,'player-rank'}, + ['reason']={false,'string-inf'} +}, function(event,args) + local player = args.player + local reason = args.reason + if Admin.is_banned(player) and Admin.is_banned(player,true) ~= 'jail' then player_return({'ExpGamingAdmin.cant-report-ban',args.player.name}) return commands.error end + Admin.temp_ban(player,event.player_index,reason) +end) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Commands/src/warnings.lua b/modules/ExpGamingAdmin/Commands/src/warnings.lua new file mode 100644 index 00000000..b3796656 --- /dev/null +++ b/modules/ExpGamingAdmin/Commands/src/warnings.lua @@ -0,0 +1,28 @@ +local Admin = self +local Role = require('ExpGamingCore.Role') + +--- Gives a warning to a player +-- @command warn +-- @param player the player to give a warning to +-- @param[opt] reason the reason the player was given a warning +commands.add_command('warn', 'Gives a player a warning', { + ['player']={true,'player-rank'}, + ['reason']={false,'string-inf'} +}, function(event,args) + local player = args.player + local reason = args.reason + if Admin.is_banned(player) then player_return{'ExpGamingAdmin.cant-report-ban',args.player.name} return commands.error end + if Role.has_flag(player,'not_reportable') then player_return{'ExpGamingAdmin.cant-report',args.player.name} return commands.error end + Admin.give_warning(player,event.player_index,reason) +end) + +--- Clears the warning of a player +-- @command clear-warnings +-- @param player the player to clear the warning of +commands.add_command('clear-warnings', 'Clears a player\'s warnings', { + ['player'] = {true,'player'} +}, function(event,args) + local player = args.player + if Admin.is_banned(player) then player_return({'ExpGamingAdmin.cant-report-ban',args.player.name}) return commands.error end + Admin.clear_warnings(player,event.player_index) +end) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Gui/control.lua b/modules/ExpGamingAdmin/Gui/control.lua new file mode 100644 index 00000000..7dd8c2e7 --- /dev/null +++ b/modules/ExpGamingAdmin/Gui/control.lua @@ -0,0 +1,202 @@ +--- Adds a gui that can be used to access all the admin commands. +-- @module ExpGamingAdmin.Gui@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias AdminGui + +-- Module Require +local Admin = require('ExpGamingAdmin') +local Gui = require('ExpGamingCore.Gui') +local Role = require('ExpGamingCore.Role') +local Game = require('FactorioStdLib.Game') +local playerInfo -- ExpGamingPlayer.playerInfo@^4.0.0 + +-- Module Define +local module_verbose = false +local AdminGui = { + on_init=function() + if loaded_modules['ExpGamingPlayer.playerInfo'] then playerInfo = require('ExpGamingPlayer.playerInfo') + else playerInfo = function(player,frame) + frame.add{ + type='label', + caption={'ExpGamingAdmin.no-info-file'} + } + end end + --code + end, + buttons={} +} + +function Admin.open(player,pre_select_player,pre_select_action) + Gui.center.clear(player) + Admin.center(player,pre_select_player,pre_select_action) +end + +-- Function Define +function AdminGui.add_button(name,caption,tooltip,callback) + AdminGui.buttons[name] = Gui.inputs.add{ + type='button', + name='admin-gui-'..name, + caption=caption, + tooltip=tooltip + }:on_event('click',function(event) + local parent = event.element.parent + local pre_select_player = parent.player and parent.player.caption or nil + callback(pre_select_player,event.player_index) + end) +end + +function AdminGui.draw(frame,filter_buttons) + local frame = frame.add{ + type='flow', + name='admin' + } + frame.add{ + type='label', + caption='', + name='player' + }.style.visible = false + local function format(btn) + btn.style.height = 30 + btn.style.width = 30 + end + for name,button in pairs(AdminGui.buttons) do + if not filter_buttons or filter_buttons[name] then format(button(frame)) end + end + return frame.player +end + +-- Gui Define +local function get_players(_player,root_frame,state) + local players = {'Select Player'} + local _players = state and game.players or game.connected_players + for _,player in pairs(_players) do + if player.name ~= _player.name then + if not Admin.is_banned or not Admin.is_banned(player) then + table.insert(players,player.name) + end + end + end + return players +end + +local online_check = Gui.inputs.add_checkbox('online-check-admin-commands',false,'Show Offline',false,function(player,element) + element.parent['player-drop-down-admin-commands'].items = get_players(player,element.parent,true) + element.parent['player-drop-down-admin-commands'].selected_index = 1 +end,function(player,element) + element.parent['player-drop-down-admin-commands'].items = get_players(player,element.parent,false) + element.parent['player-drop-down-admin-commands'].selected_index = 1 +end) + +local player_drop_down = Gui.inputs.add_drop_down('player-drop-down-admin-commands',get_players,1,function(player,selected,items,element) + element.parent.parent.player.caption = selected + local player_info_flow = element.parent.parent.info_flow + player_info_flow.clear() + if selected == 'Select Player' then return + else playerInfo(selected,player_info_flow,true) end + local role = Role.get_highest(player) + local _role = Role.get_highest(selected) + if role.index >= _role.index then element.parent.warning.caption = {'ExpGamingAdmin.warning'} + else element.parent.warning.caption = '' end +end) + +local reason_input = Gui.inputs.add_text('reason-input-admin-commands',false,'Enter Reason',function(player,text,element) + if string.len(text) < 20 or text == 'Enter Reason' then + element.parent.warning.caption = {'ExpGamingAdmin.short-reason'} + else + element.parent.warning.caption = '' + end +end) + +local action_drop_down = Gui.inputs.add_drop_down('action-drop-down-rank-change',function() return {'Select Action',unpack(Admin.action_names)} end,1,function(player,selected,items,element) + element.parent.parent.action.caption = selected + if selected == 'Jail' or selected == 'Kick' or selected == 'Ban' or selected == 'Temp Ban' then + element.parent['reason-input-admin-commands'].style.visible = true + else + element.parent['reason-input-admin-commands'].style.visible = false + end +end) + +local take_action = Gui.inputs{ + type='button', + name='admin-commands-take', + caption={'ExpGamingAdmin.take-action'} +}:on_event('click',function(event) + local dropdowns = event.element.parent + local role = Role.get_highest(event.player_index) + local _action= dropdowns.parent.action.caption ~= 'Select Action' and dropdowns.parent.action.caption or nil + local _player = Game.get_player(dropdowns.parent.player.caption) + if not _player or not _action then dropdowns.warning.caption = {'ExpGamingAdmin.invalid'} return end + local _role = Role.get_highest(_player) + if role.index >= _role.index then dropdowns.warning.caption = {'ExpGamingAdmin.rank-high'} return end + local _reason = dropdowns['reason-input-admin-commands'] and dropdowns['reason-input-admin-commands'].text + if (_action == 'Jail' or _action == 'Kick' or _action == 'Ban' or _action == 'Temp Ban') and (_reason == 'Enter Reason' or string.len(_reason) < 10) then return end + Admin.take_action(_action,_player,event.player_index,_reason) + Gui.center.clear(event) +end) + +Admin.center = Gui.center{ + name='admin-commands', + caption='utility/danger_icon', + tooltip={'ExpGamingAdmin.tooltip'}, + draw=function(self,frame,pre_select_player,pre_select_action) + frame.caption={'ExpGamingAdmin.name'} + frame = frame.add{ + type='flow', + direction='horizontal' + } + local dropdowns = frame.add{ + type='flow', + direction='vertical' + } + local player_info_flow = frame.add{ + name='info_flow', + type='flow', + direction='vertical' + } + player_info_flow.style.height = 280 + player_info_flow.style.width = 200 + local label = dropdowns.add{ + type='label', + caption={'ExpGamingAdmin.message'} + } + label.style.single_line = false + label.style.width = 200 + online_check:draw(dropdowns) + local _drop = player_drop_down:draw(dropdowns) + if pre_select_player then Gui.set_dropdown_index(_drop,pre_select_player.name) end + _drop = action_drop_down:draw(dropdowns) + Gui.set_dropdown_index(_drop,pre_select_action) + local _text = reason_input:draw(dropdowns) + if pre_select_action == 'Jail' or pre_select_action == 'Kick' or pre_select_action == 'Ban' then + _text.style.visible = true else _text.style.visible = false + end + if pre_select_player then playerInfo(pre_select_player,player_info_flow,true) end + _text.style.width = 200 + label = dropdowns.add{ + name='warning', + type='label', + caption='', + style='bold_red_label' + } + label.style.single_line = false + label.style.width = 200 + take_action:draw(dropdowns) + local caption = pre_select_player and pre_select_player.name or '' + frame.add{ + name='player', + type='label', + caption=caption + }.style.visible = false + caption = pre_select_action or '' + frame.add{ + name='action', + type='label', + caption=caption + }.style.visible = false + end +} + +-- Module Return +-- calling will draw the admin buttons to that frame +return setmetatable(AdminGui,{__call=function(self,...) return self.draw(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Gui/softmod.json b/modules/ExpGamingAdmin/Gui/softmod.json new file mode 100644 index 00000000..97fc27d7 --- /dev/null +++ b/modules/ExpGamingAdmin/Gui/softmod.json @@ -0,0 +1,23 @@ +{ + "name": "ExpGamingAdmin.Gui", + "version": "4.0.0", + "description": "Adds a gui that can be used to access all the admin commands.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Admin", + "ExpGaming", + "Commands", + "Gui" + ], + "dependencies": { + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingCore.Role": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingPlayer": "?^4.0.0", + "ExpGamingPlayer.playerInfo": "?^4.0.0", + "mod-gui": "*", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/Jail/control.lua b/modules/ExpGamingAdmin/Jail/control.lua new file mode 100644 index 00000000..e868d943 --- /dev/null +++ b/modules/ExpGamingAdmin/Jail/control.lua @@ -0,0 +1,50 @@ +--- Adds a jail function to the admin set, require ExpGamingRole to work. +-- @module ExpGamingAdmin.Jail@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Admin = require('ExpGamingAdmin') +local AdminGui = require('ExpGamingAdmin.Gui') +local Server = require('ExpGamingCore.Server') +local Role = require('ExpGamingCore.Role') +local Color -- FactorioStdLib.Color@^0.8.0 +local Sync -- ExpGamingCore.Sync@^4.0.0 + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Sync'] then Sync = require('ExpGamingCore.Sync') end + if loaded_modules['FactorioStdLib.Color'] then Color = require('FactorioStdLib.Color') end + end +} + +-- Function Define +AdminGui.add_button('jail','utility/clock',{'ExpGamingAdmin.tooltip-jail'},function(player,byPlayer) + Admin.open(byPlayer,player,'Jail') +end) + +function Admin.jail(player,by_player,reason) + player, by_player = Admin.valid_players(player,by_player) + if not player then return end + reason = Admin.create_reason(reason,by_player.name) + Admin.set_banned(player,'jail') + if Sync then Sync.emit_embedded{ + title='Player Jail', + color=Color.to_hex(defines.textcolor.med), + description='There was a player jailed.', + ['Player:']='<>'..player.name, + ['By:']='<>'..by_player.name, + ['Reason:']=reason + } end + Role.meta.last_jail = player.name + Server.interface(Role.assign,true,player,'Jail',by_player.name) + Server.interface(Role.unassign,true,player,Role.get(player),by_player.name) +end + +Admin.add_action('Jail',Admin.jail) + +-- Module Return +return setmetatable(ThisModule,{__call=Admin.jail}) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Jail/softmod.json b/modules/ExpGamingAdmin/Jail/softmod.json new file mode 100644 index 00000000..c6dba711 --- /dev/null +++ b/modules/ExpGamingAdmin/Jail/softmod.json @@ -0,0 +1,24 @@ +{ + "name": "ExpGamingAdmin.Jail", + "version": "4.0.0", + "description": "Adds a jail function to the admin set, require ExpGamingRole to work.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Jail", + "Roles", + "Admin", + "ExpGaming" + ], + "dependencies": { + "ExpGamingAdmin.Gui": "^4.0.0", + "ExpGamingCore.Server": "^4.0.0", + "ExpGamingCore.Role": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Color": "?^0.8.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingAdmin.ClearInventory": "?^4.0.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/Kick/control.lua b/modules/ExpGamingAdmin/Kick/control.lua new file mode 100644 index 00000000..e36eef2e --- /dev/null +++ b/modules/ExpGamingAdmin/Kick/control.lua @@ -0,0 +1,47 @@ +--- Adds a kick function to the admin function set. +-- @module ExpGamingAdmin.Kick@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Admin = require('ExpGamingAdmin') +local AdminGui = require('ExpGamingAdmin.Gui') +local Server = require('ExpGamingCore.Server') +local Game = require('FactorioStdLib.Game') +local Color -- FactorioStdLib.Color@^0.8.0 +local Sync -- ExpGamingCore.Sync@^4.0.0 + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Sync'] then Sync = require('ExpGamingCore.Sync') end + if loaded_modules['FactorioStdLib.Color'] then Color = require('FactorioStdLib.Color') end + end +} +-- Function Define +AdminGui.add_button('Kick','utility/warning_icon',{'ExpGamingAdmin.tooltip-kick'},function(player,byPlayer) + Admin.open(byPlayer,player,'Kick') +end) + +function Admin.kick(player,by_player,reason) + player = Game.get_player(player) + reason = Admin.create_reason(reason,by_player_name) + local by_player_name = Game.get_player(by_player) and Game.get_player(by_player).name or '' + if Sync then Sync.emit_embedded{ + title='Player Kick', + color=Color.to_hex(defines.textcolor.high), + description='There was a player kicked.', + ['Player:']='<>'..player.name, + ['By:']='<>'..by_player_name, + ['Reason:']=reason + } end + if Admin.move_inventory then Admin.move_inventory(player) end + Server.interface(game.kick_player,true,player,reason) +end + +Admin.add_action('Kick',Admin.kick) + +-- Module Return +return setmetatable(ThisModule,{__call=Admin.kick}) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Kick/softmod.json b/modules/ExpGamingAdmin/Kick/softmod.json new file mode 100644 index 00000000..26baa78c --- /dev/null +++ b/modules/ExpGamingAdmin/Kick/softmod.json @@ -0,0 +1,23 @@ +{ + "name": "ExpGamingAdmin.Kick", + "version": "4.0.0", + "description": "Adds a kick function to the admin function set.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Admin", + "ExpGaming", + "Kick", + "Commands" + ], + "dependencies": { + "ExpGamingAdmin.Gui": "^4.0.0", + "ExpGamingCore.Server": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Color": "?^0.8.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingAdmin.ClearInventory": "?^4.0.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/Reports/control.lua b/modules/ExpGamingAdmin/Reports/control.lua new file mode 100644 index 00000000..56fad0ba --- /dev/null +++ b/modules/ExpGamingAdmin/Reports/control.lua @@ -0,0 +1,162 @@ +--- Adds a report system into the game that can also push notifactions to discord. +-- @module ExpGamingAdmin.Reports@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Admin = require('ExpGamingAdmin') +local Role = require('ExpGamingCore.Role') +local Gui = require('ExpGamingCore.Gui') +local Game = require('FactorioStdLib.Game') +local Color -- FactorioStdLib.Color@^0.8.0 +local Sync -- ExpGamingCore.Sync@^4.0.0 + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Sync'] then Sync = require('ExpGamingCore.Sync') end + if loaded_modules['FactorioStdLib.Color'] then Color = require('FactorioStdLib.Color') end + end +} + +-- Global Define +local global = global{ + reports={}, + verified={} +} + +-- Local Variables +local report_to_warnings = 1 -- used in count_reports +local verified_to_warnings = 3 -- used in count_reports +local reports_needed_for_jail = 6 + +-- Function Define +local function report_message(player,by_player,reason) + player, by_player = Admin.valid_players(player,by_player) + if not player then return end + if Admin.is_banned(player,true) == 'report' then return end + Role.print(Role.meta.groups.User.lowest,{'ExpGamingAdmin.low-print',player.name,reason},defines.textcolor.info,true) + Role.print(Role.meta.groups.Admin.lowest,{'ExpGamingAdmin.high-print',player.name,by_player.name,reason},defines.textcolor.med) + if Sync then Sync.emit_embedded{ + title='Player Report', + color=Color.to_hex(defines.textcolor.med), + description='A player was reported.', + ['Player:']='<>'..player.name, + ['By:']='<>'..by_player.name, + ['Reason:']=reason + } end +end + +local function cheak_reports(player) + player = Game.get_player(player) + if not player then return end + local reports = Admin.count_reports(player) + if reports >= reports_needed_for_jail and Role.get_highest(player).group.name ~= 'Jail' then + Admin.jail(player,'','Too many user reports. Contact an Admin to be unjailed.') + end +end + +function Admin.count_reports(player) + player = Game.get_player(player) + if not player then return 0 end + local _count = 0 + if global.reports[player.name] then + for _ in pairs(global.reports[player.name]) do + _count=_count+report_to_warnings + end + end + if global.verified[player.name] then + for _ in pairs(global.verified[player.name]) do + _count=_count+verified_to_warnings + end + end + return _count +end + +function Admin.report(player,by_player,reason) + player, by_player = Admin.valid_players(player,by_player) + if not player or Role.has_flag(player,'not_reportable') then return end + if Admin.is_banned(by_player) or Role.has_flag(by_player,'is_jail') then return end + if Role.has_flag(by_player,'is_verified') then + global.verified[player.name] = global.verified[player.name] or {} + local reports = global.verified[player.name] + for _,value in pairs(reports) do + if value[1] == by_player.name then return end + end + table.insert(reports,{by_player.name,reason}) + else + global.reports[player.name] = global.reports[player.name] or {} + local reports = global.reports[player.name] + for _,value in pairs(reports) do + if value[1] == by_player.name then return end + end + table.insert(reports,{by_player.name,reason}) + end + report_message(player,by_player,reason) + cheak_reports(player) +end + +function Admin.clear_reports(player,by_player,no_emit) + player, by_player = Admin.valid_players(player,by_player) + if not player then return end + global.reports[player.name]={} + global.verified[player.name]={} + if not no_emit and Sync then + Sync.emit_embedded{ + title='Player Clear', + color=Color.to_hex(defines.textcolor.low), + description='A player had their reports cleared.', + ['Player:']='<>'..player.name, + ['By:']='<>'..by_player.name, + } + end +end + +local confirm_report = Gui.inputs{ + type='button', + name='admin-report-confirm', + caption='utility/spawn_flag', + tooltip={'ExpGamingAdmin.report'} +}:on_event('click',function(event) + local parent = event.element.parent + local player = Game.get_player(parent.player.caption) + local reason = parent.reason.text + Admin.report(player,event.player_index,reason) + Gui.center.clear(event.player_index) +end) + +Admin.report_btn = Gui.inputs{ + type='button', + name='admin-report', + caption='utility/spawn_flag', + tooltip={'ExpGamingAdmin.report'} +}:on_event('click',function(event) + local parent = event.element.parent + local player = Game.get_player(parent.children[1].name) + if not player then return end + local _player = Game.get_player(event) + Gui.center.clear(_player) + local frame = Gui.center.get_flow(_player).add{ + type='frame', + name='report-gui' + } + _player.opened=frame + frame.caption={'ExpGamingAdmin.report'} + frame.add{ + type='textfield', + name='reason' + }.style.width = 300 + local btn = confirm_report:draw(frame) + btn.style.height = 30 + btn.style.width = 30 + frame.add{ + type='label', + name='player', + caption=player.name + }.style.visible = false +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Reports/softmod.json b/modules/ExpGamingAdmin/Reports/softmod.json new file mode 100644 index 00000000..4aee29bb --- /dev/null +++ b/modules/ExpGamingAdmin/Reports/softmod.json @@ -0,0 +1,25 @@ +{ + "name": "ExpGamingAdmin.Reports", + "version": "4.0.0", + "description": "Adds a report system into the game that can also push notifactions to discord.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Report", + "Player", + "Admin", + "ExpGaming", + "Player List", + "Commands" + ], + "dependencies": { + "ExpGamingCore.Server": "^4.0.0", + "ExpGamingCore.Role": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Color": "?^0.8.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/Teleport/control.lua b/modules/ExpGamingAdmin/Teleport/control.lua new file mode 100644 index 00000000..f745add4 --- /dev/null +++ b/modules/ExpGamingAdmin/Teleport/control.lua @@ -0,0 +1,43 @@ +--- Adds three function to admin: tp, bring and go to, these all move the player +-- @module ExpGamingAdmin.Teleport@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Admin = require('ExpGamingAdmin') +local AdminGui = require('ExpGamingAdmin.Gui') +local Game = require('FactorioStdLib.Game') + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Function Define +AdminGui.add_button('Go To','utility/export_slot',{'ExpGamingAdmin.tooltip-go-to'},function(player,byPlayer) + Admin.go_to(player,byPlayer) +end) +AdminGui.add_button('Bring','utility/import_slot',{'ExpGamingAdmin.tooltip-bring'},function(player,byPlayer) + Admin.bring(player,byPlayer) +end) + +function Admin.tp(from_player, to_player) + local _from_player = Game.get_player(from_player) + local _to_player = Game.get_player(to_player) + if not _from_player or not _to_player then return end + _from_player.teleport(_to_player.surface.find_non_colliding_position('player',_to_player.position,32,1),_to_player.surface) +end + +function Admin.go_to(player,by_player) + Admin.tp(by_player, player) +end + +function Admin.bring(player,by_player) + Admin.tp(player, by_player) +end + +Admin.add_action('Go To',Admin.go_to) +Admin.add_action('Bring',Admin.bring) + +-- Module Return +return setmetatable(ThisModule,{__call=Admin.tp}) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Teleport/softmod.json b/modules/ExpGamingAdmin/Teleport/softmod.json new file mode 100644 index 00000000..2bebb4c4 --- /dev/null +++ b/modules/ExpGamingAdmin/Teleport/softmod.json @@ -0,0 +1,22 @@ +{ + "name": "ExpGamingAdmin.Teleport", + "version": "4.0.0", + "description": "Adds three function to admin: tp, bring and go to, these all move the player.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Tp", + "Bring", + "Go To", + "Admin", + "ExpGaming", + "Teleport", + "Commands" + ], + "dependencies": { + "ExpGamingAdmin.Gui": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/TempBan/control.lua b/modules/ExpGamingAdmin/TempBan/control.lua new file mode 100644 index 00000000..5848fd5c --- /dev/null +++ b/modules/ExpGamingAdmin/TempBan/control.lua @@ -0,0 +1,48 @@ +--- Adds a temp ban function to the admin set, requires ExpGamingCore.Role to work. +-- @module ExpGamingAdmin.KicTempBan@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Admin = require('ExpGamingAdmin') +local Server = require('ExpGamingCore.Server') +local Role = require('ExpGamingCore.Role') +local Game = require('FactorioStdLib.Game') +local Color -- FactorioStdLib.Color@^0.8.0 +local Sync -- ExpGamingCore.Sync@^4.0.0 + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Sync'] then Sync = require('ExpGamingCore.Sync') end + if loaded_modules['FactorioStdLib.Color'] then Color = require('FactorioStdLib.Color') end + end +} + +-- Function Define +function Admin.temp_ban(player,by_player,reason) + local player = Game.get_player(player) + local by_player_name = Game.get_player(by_player) and Game.get_player(by_player).name or '' + if not player or Admin.is_banned(player) then return end + Admin.set_banned(player,'temp') + if Sync then Sync.emit_embedded{ + title='Player Temp-Ban', + color=Color.to_hex(defines.textcolor.high), + description='A player was jailed.', + ['Player:']='<>'..player.name, + ['By:']='<>'..by_player_name, + ['Reason:']=Admin.create_reason(reason,by_player_name) + } end + game.print({'ExpGamingAdmin.temp-ban',player.name,by_player_name,reason},defines.textcolor.info) + if Admin.move_inventory then Admin.move_inventory(player) end + Role.meta.last_jail = player.name + Server.interface(Role.unassign,true,player,Role.get(player),by_player_name) + Server.interface(Role.assign,true,player,'Jail',by_player_name) +end + +Admin.add_action('Temp Ban',Admin.temp_ban) + +-- Module Return +return setmetatable(ThisModule,{__call=Admin.temp_ban}) \ No newline at end of file diff --git a/modules/ExpGamingAdmin/TempBan/softmod.json b/modules/ExpGamingAdmin/TempBan/softmod.json new file mode 100644 index 00000000..64853ebb --- /dev/null +++ b/modules/ExpGamingAdmin/TempBan/softmod.json @@ -0,0 +1,24 @@ +{ + "name": "ExpGamingAdmin.TempBan", + "version": "4.0.0", + "description": "Adds a temp ban function to the admin set, requires ExpGamingCore.Role to work.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Jail", + "Temp Ban", + "Admin", + "ExpGaming", + "Roles" + ], + "dependencies": { + "ExpGamingCore.Server": "^4.0.0", + "ExpGamingCore.Role": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Color": "?^0.8.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingAdmin.ClearInventory": "?^4.0.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/Warnings/control.lua b/modules/ExpGamingAdmin/Warnings/control.lua new file mode 100644 index 00000000..07cd6994 --- /dev/null +++ b/modules/ExpGamingAdmin/Warnings/control.lua @@ -0,0 +1,141 @@ +--- Adds a warning system into the admin set which can be used by admins and the script. +-- @module ExpGamingAdmin.Warnings@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Admin = require('ExpGamingAdmin') +local Server = require('ExpGamingCore.Server') +local Role = require('ExpGamingCore.Role') +local Game = require('FactorioStdLib.Game') +local Color -- FactorioStdLib.Color@^0.8.0 +local Sync -- ExpGamingCore.Sync@^4.0.0 + +-- Local Variables +local take_action = 8 -- the first admin given warning jumps to this number, this case kick-warn is giving +local remove_warnings_time = {} +local min_time_to_remove_warning = 18000 -- this is in ticks +local punishments = { + {'nothing'}, + {'nothing'}, + {'nothing'}, + {'nothing'}, + {'nothing'}, + {'message',{'ExpGamingAdmin-Warnings.message'},defines.textcolor.info}, + {'message',{'ExpGamingAdmin-Warnings.message'},defines.textcolor.info}, + {'message',{'ExpGamingAdmin-Warnings.kick-warn'},defines.textcolor.med}, + {'kick'}, + {'message',{'ExpGamingAdmin-Warnings.temp-warn'},defines.textcolor.high}, + {'temp-ban'}, + {'message',{'ExpGamingAdmin-Warnings.ban-warn'},defines.textcolor.high}, + {'message',{'ExpGamingAdmin-Warnings.last-warn'},defines.textcolor.crit}, + {'ban'} +} + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Sync'] then Sync = require('ExpGamingCore.Sync') end + if loaded_modules['FactorioStdLib.Color'] then Color = require('FactorioStdLib.Color') end + if loaded_modules['ExpGamingAdmin.Reports'] then + take_action = take_action + 1 + table.insert(punishments,take_action,{'report',{'ExpGamingAdmin-Warnings.reported'},defines.textcolor.med}) + end + end, + on_post=function() + local highest = nil + for _,role in pairs(Role.roles) do + local power = role.index + if not highest and not role.not_reportable then highest = power-1 end + local _power = power; if highest then _power = power-highest end + if role.not_reportable then remove_warnings_time[power] = 0 + else remove_warnings_time[power] = min_time_to_remove_warning*_power end + end + end +} + +-- Global Define +local global = global{} + +-- Function Define +local function give_punishment(player,by_player,reason) + player, by_player = Admin.valid_players(player,by_player) + reason = reason or 'No Other Reason' + local warnings = Admin.get_warnings(player) + local punishment = punishments[warnings] + if not punishment or punishment[1] == 'nothing' then return + elseif punishment[1] == 'message' then + local message = punishment[2] + local colour = punishment[3] + player_return(message,colour,player) + elseif punishment[1] == 'report' then + local message = punishment[2] + local colour = punishment[3] + player_return(message,colour,player) + Admin.report(player,'',reason) + elseif punishment[1] == 'kick' then + Admin.kick(player,by_player,'Too Many Warnings: '..warnings-(take_action-1)..' Also: '..reason) + elseif punishment[1] == 'temp-ban' then + Admin.temp_ban(player,by_player,'Too Many Warnings: '..warnings-(take_action-1)..' Also: '..reason) + elseif punishment[1] == 'ban' then + Admin.ban(player,by_player,'Too Many Warnings: '..warnings-(take_action-1)..' Also: '..reason) + end +end + +function Admin.get_warnings(player) + player = Game.get_player(player) + return global[player.name] or 0 +end + +function Admin.give_warning(player,by_player,reason,min) + player, by_player = Admin.valid_players(player,by_player) + if not player then return end + min = Game.get_player(by_player) and Game.get_player(by_player) ~= SERVER and take_action or min or 0 + local warnings = Admin.get_warnings(player) + if warnings < min then warnings = min-1 end + warnings = warnings+1 + global[player.name] = warnings + if warnings > take_action then + player_return({'ExpGamingAdmin-Warnings.warning-given-by',by_player.name},defines.textcolor.info,player) + game.print({'ExpGamingAdmin-Warnings.player-warning',player.name,by_player.name,reason}) + end + give_punishment(player,by_player,reason) +end + +function Admin.clear_warnings(player,by_player,no_emit) + player, by_player = Admin.valid_players(player,by_player) + if not player then return end + global[player.name]=nil + if not no_emit and Sync then + Sync.emit_embedded{ + title='Player Clear', + color=Color.to_hex(defines.textcolor.low), + description='A player had their warnings cleared.', + ['Player:']='<>'..player.name, + ['By:']='<>'..by_player.name, + } + end +end + +-- Event Handlers Define +script.on_event(defines.events.on_tick,function(event) + if (game.tick % min_time_to_remove_warning) == 0 then + for name,warnings in pairs(global) do + if warnings > 0 then + local role = Role.get_highest(name) + local time_to_remove = remove_warnings_time[role.index] + if (game.tick % time_to_remove) == 0 then + global[name]=warnings-1 + if global[name] > 5 then + player_return({'ExpGamingAdmin-Warnings.remove-warn',global[name],tick_to_display_format(time_to_remove)},defines.textcolor.low,name) + end + end + end + end + end +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Warnings/locale/de.cfg b/modules/ExpGamingAdmin/Warnings/locale/de.cfg new file mode 100644 index 00000000..c48f518a --- /dev/null +++ b/modules/ExpGamingAdmin/Warnings/locale/de.cfg @@ -0,0 +1,11 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=This Warnings Was Given By: __1__ +player-warning=__1__ was given a warning by __2__ reason: __3__ +temp-ban=__1__ was temp-ban by __2__ and will remain in jail untill next reset +remove-warn=You are had a warning Removed, you have __1__ warnings, next removed in __2__ +message=You Are Currently Reciving Warnings From The Script, This Will Continue Unless You Cease And Desist +reported=You Have Been Reported To The Admins By The Script, Further Acction May Be Taken If You Do Not Cease And Desist. +kick-warn=You Are On A Warning To Be KICKED, The Script Will Auto Kick If You Do Not Cease And Desist. +temp-warn=You Are On A Warning To Be TEMP BANNED, The Script Will Auto Ban If You Do Not Cease And Desist. +ban-warn=You Are On A Warning To Be BANNED, The Script Will Auto Ban If You Do Not Cease And Desist. +last-warn=YOU ARE ON A LAST WARNING TO BE BANNED, THE SCRIPT WILL AUTO BAN IF YOU DO NOT CEASE AND DESIST. \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Warnings/locale/en.cfg b/modules/ExpGamingAdmin/Warnings/locale/en.cfg new file mode 100644 index 00000000..01715fc7 --- /dev/null +++ b/modules/ExpGamingAdmin/Warnings/locale/en.cfg @@ -0,0 +1,10 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=This warning was given by: __1__ +player-warning=__1__ was given a warning by __2__ for: __3__ +remove-warn=One of your warnings expired. You have __1__ warnings left, next warning will be removed in __2__ +message=You are currently being warned by the system. These will continue until you cease and desist. +reported=You have been reported to the admins by the system. Further action may be taken if you do not cease and desist. +kick-warn=This is your last warning before you get kicked. The system will automatically kick you if you do not cease and desist. +temp-warn=This is your last warning before you get temporary banned. The system will automatically ban you if you do not cease and desist. +ban-warn=WARNING: This is your last warning before you get BANNED. The system will automatically BAN you if you do not cease and desist. +last-warn=WARNING: This is your last warning before you get PERMANENTLY BANNED. The system will automatically PERMANENTLY BAN you if you do not cease and desist. diff --git a/modules/ExpGamingAdmin/Warnings/locale/fr.cfg b/modules/ExpGamingAdmin/Warnings/locale/fr.cfg new file mode 100644 index 00000000..c48f518a --- /dev/null +++ b/modules/ExpGamingAdmin/Warnings/locale/fr.cfg @@ -0,0 +1,11 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=This Warnings Was Given By: __1__ +player-warning=__1__ was given a warning by __2__ reason: __3__ +temp-ban=__1__ was temp-ban by __2__ and will remain in jail untill next reset +remove-warn=You are had a warning Removed, you have __1__ warnings, next removed in __2__ +message=You Are Currently Reciving Warnings From The Script, This Will Continue Unless You Cease And Desist +reported=You Have Been Reported To The Admins By The Script, Further Acction May Be Taken If You Do Not Cease And Desist. +kick-warn=You Are On A Warning To Be KICKED, The Script Will Auto Kick If You Do Not Cease And Desist. +temp-warn=You Are On A Warning To Be TEMP BANNED, The Script Will Auto Ban If You Do Not Cease And Desist. +ban-warn=You Are On A Warning To Be BANNED, The Script Will Auto Ban If You Do Not Cease And Desist. +last-warn=YOU ARE ON A LAST WARNING TO BE BANNED, THE SCRIPT WILL AUTO BAN IF YOU DO NOT CEASE AND DESIST. \ No newline at end of file diff --git a/modules/ExpGamingAdmin/Warnings/locale/nl.cfg b/modules/ExpGamingAdmin/Warnings/locale/nl.cfg new file mode 100644 index 00000000..104ef981 --- /dev/null +++ b/modules/ExpGamingAdmin/Warnings/locale/nl.cfg @@ -0,0 +1,11 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=Deze waarschuwing is gegeven door: __1__ +player-warning=__1__ is gewaarschuwd door __2__ met de reden: __3__ +temp-ban=__1__ is verbannen door __2__ en is gejailed tot de volgende reset. +remove-warn=Een waarschuwing is verlopen. Je hebt nu nog maar __1__ waarschuwing, volgende waarschuwing verloopt in __2__ +message=Je ontvangt waarschuwingen door het systeem. Deze waarschuwingen stoppen niet tot je stopt met wat je verkeerd doet. +reported=Je bent gerapporteerd aan de administrators door het systeem. Je zal bestraft worden als je niet stopt met wat je verkeerd doet. +kick-warn=WAARSCHUWING: Dit is je laatste waarschuwing voordat je gekickt wordt. +temp-warn=WAARSCHUWING: Dit is je laatste waarschuwing voordat je tijdelijk verbannen wordt. +ban-warn=WAARSCHUWING: Dit is je laatste waarschuwing voordat je permanent verbannen wordt. +last-warn=DIT IS JE LAATSTE WAARSCHUWING. Het systeem zal je automatisch VERBANNEN als je niet stopt met wat je verkeerd doet. diff --git a/modules/ExpGamingAdmin/Warnings/locale/sv-SE.cfg b/modules/ExpGamingAdmin/Warnings/locale/sv-SE.cfg new file mode 100644 index 00000000..9358b9cf --- /dev/null +++ b/modules/ExpGamingAdmin/Warnings/locale/sv-SE.cfg @@ -0,0 +1,10 @@ +[ExpGamingAdmin-Warnings] +warning-given-by=Den här varningen gavs av: __1__ +player-warning=__1__ var tillfälligt bannlyst av __2__ och kommer att förbli i fängelset tills nästa återställning (reset) +remove-warn=En av dina varningar har gått ut. Du har __1__ varning kvar, nästa varning kommer at tas bort om __2__ +message=Du får för nuvarande varningar av systemet. De kommer fortsätta tills du upphör med överträdelsen. +reported= Du har blivit rapporterad till administrationen av systemet. Mer påföljd kan komma att tas om du inte upphör med överträdelsen. +kick-warn=Det här är din sista varning innan du blir sparkad. Systemet kommer att automatisk sparka dig om du inte upphör med överträdelsen +temp-warn=Det här är din sista varning innan du blir tillfälligt bannlyst. Systemet kommer att automatiskt bannlysa dig om du inte upphör överträdelsen +ban-warn=VARNING: Det här är din sista varning innan du blir bannlyst. Systemet kommer att automatisk bannlysa dig om du inte upphör med överträdelsen. +last-warn=VARNING: Det här är din sista varning innan du blir permanent bannlyst. Systemet kommer att automatiskt permanent bannlysa dig om du inte upphör med överträdelsen. diff --git a/modules/ExpGamingAdmin/Warnings/softmod.json b/modules/ExpGamingAdmin/Warnings/softmod.json new file mode 100644 index 00000000..70c11140 --- /dev/null +++ b/modules/ExpGamingAdmin/Warnings/softmod.json @@ -0,0 +1,26 @@ +{ + "name": "ExpGamingAdmin.Warnings", + "version": "4.0.0", + "description": "Adds a warning system into the admin set which can be used by admins and the script.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Warning", + "Admin", + "ExpGaming", + "Report", + "Kick", + "Punishments", + "Ban" + ], + "dependencies": { + "ExpGamingCore.Server": "^4.0.0", + "ExpGamingCore.Role": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Color": "?^0.8.0", + "ExpGamingAdmin.Reports": "?^4.0.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingAdmin@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingAdmin/control.lua b/modules/ExpGamingAdmin/control.lua new file mode 100644 index 00000000..4d4f20e1 --- /dev/null +++ b/modules/ExpGamingAdmin/control.lua @@ -0,0 +1,102 @@ +--- The base functions required to make the others work. +-- @module ExpGamingAdmin@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias Admin + +-- Module Require +local Game = require('FactorioStdLib.Game') +local Color = require('FactorioStdLib.Color') +local Role -- ExpGamingCore.Role@^4.0.0 +local Sync -- ExpGamingCore.Sync@^4.0.0 +local Server -- ExpGamingCore.Server@^4.0.0 + +-- Module Define +local module_verbose = false +local Admin = { + on_init=function() + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + if loaded_modules['ExpGamingCore.Sync'] then Sync = require('ExpGamingCore.Sync') end + if loaded_modules['ExpGamingCore.Server'] then + Server = require('ExpGamingCore.Server') + Server.add_module_to_interface('Admin','ExpGamingAdmin') + end + end, + actions={}, + action_functions={}, + action_names={} +} + +-- Global Define +local global = global{ + banned = {} +} + +-- Function Define +function Admin.valid_players(player,by_player) + player = Game.get_player(player) + by_player = Game.get_player(by_player) or SERVER + return player, by_player +end + +function Admin.create_reason(reason,name) + reason = reason or 'No Reason' + if not string.find(string.lower(reason),string.lower(name)) then reason = reason..' - '..name end + if Sync and Sync.info.date ~= '0000/00/00' and not string.find(string.lower(reason),Sync.info.date) then reason = reason..' - '..Sync.info.date end + if not string.find(string.lower(reason),'appeal') then reason = reason..' - Vist www.explosivegaming.nl to appeal.' end + return reason +end + +function Admin.allowed(player) + player = Game.get_player(player) + if Role then + return Role.allowed(player,'admin-commands') + else return player.admin end +end + +function Admin.set_banned(player,set) + player = Game.get_player(player) + if not player then return false end + global.banned[player.name] = set +end + +function Admin.is_banned(player,detail) + player = Game.get_player(player) + if not player then return false end + local banned = global.banned[player.name] + if banned == true then return true end + if not banned then return false end + if detail then return banned + else return true end +end + +function Admin.add_action(action,callback) + verbose('Added admin action: '..action) + Admin.actions[string.lower(action)] = table.insert(Admin.action_names,action) + Admin.action_functions[string.lower(action)] = callback +end + +function Admin.take_action(action,player,by_player,reason) + if Admin.action_functions[string.lower(action)] then Admin.action_functions[string.lower(action)](player,by_player,reason) end + if Admin[action] then Admin[action](player,by_player,reason) end +end + +function Admin.clear_player(player,by_player) + player, by_player = Admin.valid_players(player,by_player) + if not player then return end + if Server and Admin.is_banned(player,true) == true then Server.interface(game.unban_player,true,player) end + if Admin.clear_warnings then Admin.clear_warnings(player,by_player,true) end + if Admin.clear_reports then Admin.clear_reports(player,by_player,true) end + if Server and Role.has_flag(player,'is_jail') then Server.interface(Role.revert,true,player,by_player,2) end + if Sync then Sync.emit_embedded{ + title='Player Clear', + color=Color.to_hex(defines.textcolor.low), + description='A player had their reports and warnings cleared.', + ['Player:']='<>'..player.name, + ['By:']='<>'..by_player.name, + } end + Admin.set_banned(player,false) +end + +-- Module Return +return Admin \ No newline at end of file diff --git a/modules/ExpGamingAdmin/locale/de.cfg b/modules/ExpGamingAdmin/locale/de.cfg new file mode 100644 index 00000000..299b094f --- /dev/null +++ b/modules/ExpGamingAdmin/locale/de.cfg @@ -0,0 +1,15 @@ +[ExpGamingAdmin] +name=Admin-Befehle +tooltip=Die mächtigsten Befehle sind hier zuhause. +no-info-file=Die Informationsdatei wurde nicht gefunden. +message=Wähle einen Spieler und eine Aktion. Stell vor dem Ausführen sicher, dass der Richtige ist! +warning=Achtung, dieser Spieler hat einen höheren Rang als du selbst, weshalb du seinen Rang nicht ändern kannst. +short-reason=Achtung, dies ist ein sehr kurzer Grund. Bitte versuche, mehr Informationen anzugeben. (Warning: The reason is too short. UPDATE) +rank-high=Dieser Spieler hat einen hohen Rang. Bitte benutze nur Ingame-Befehle gegen diese Person, wenn du dir sicher bist! +invalid=Der Spieler oder die Aktion war ungültig. Bitte versuche es noch einmal! +take-action= Ergreife Maßnahme +tooltip-ban=Banne Spieler +tooltip-kick=Kicke Spieler +tooltip-jail=Sperre Spieler ins Gefängnis +tooltip-go-to=Gehe zum Spieler +tooltip-bring=Bringe den Spieler zu dir \ No newline at end of file diff --git a/modules/ExpGamingAdmin/locale/en.cfg b/modules/ExpGamingAdmin/locale/en.cfg new file mode 100644 index 00000000..f240bac1 --- /dev/null +++ b/modules/ExpGamingAdmin/locale/en.cfg @@ -0,0 +1,21 @@ +[ExpGamingAdmin] +name=Admin Commands +tooltip=Admin commands make their home here +no-info-file=No info file was found +message=Please select a player and an action to take. Make sure to choose the correct one! +warning=Warning: This player outranks you. Therefore, you cannot edit their rank. +short-reason=Warning: The reason is too short. +rank-high=Warning: This player outranks you. Therefore, you cannot edit their rank. +invalid=The player or the action is invalid. Please try again! +take-action=Take Action +tooltip-ban=Ban Player +tooltip-kick=Kick Player +tooltip-jail=Jail Player +tooltip-go-to=Go To Player +tooltip-bring=Bring Player +temp-ban=__1__ was temporary banned by __2__ and will remain in jail until next reset +report=Report Player +cant-report-ban=Invalid player as player is banned; Either unban or use /clear-all +low-print=__1__ has been reported by a user for: __2__ +high-print=__1__ has been reported by __2__ for: __3__ +cant-report=This player can't be reported. \ No newline at end of file diff --git a/modules/ExpGamingAdmin/locale/fr.cfg b/modules/ExpGamingAdmin/locale/fr.cfg new file mode 100644 index 00000000..f882fc1c --- /dev/null +++ b/modules/ExpGamingAdmin/locale/fr.cfg @@ -0,0 +1,15 @@ +[ExpGamingAdmin] +name=Commandes Admin +tooltip=Des commandes très puissantes résident ici. +no-info-file=Aucun fichier info trouvé +message=Veuillez sélectionner un joueur et une action, faites en sorte que ce soit la bonne ! +warning=Attention, ce joueur est de rang supérieur au vôtre, vous ne pouvez le modifier. +short-reason=Attention, la raison indiquée est trop courte. Soyez concis mais aussi précis. (Warning: The reason is too short. UPDATE) +rank-high=Ce joueur est de rang supérieur, veuillez utiliser une commande dont vous maîtriser l'utilisation ! +invalid=Le Joueur ou l'action est invalide, ré-essayez ! +take-action=Agir +tooltip-ban=Bannir un Joueur +tooltip-kick=Exclure un Joueur +tooltip-jail=Emprisonner un Joueur +tooltip-go-to=Aller à la position d'un Joueur +tooltip-bring=Amener le Joueur à soi diff --git a/modules/ExpGamingAdmin/locale/nl.cfg b/modules/ExpGamingAdmin/locale/nl.cfg new file mode 100644 index 00000000..ff47947a --- /dev/null +++ b/modules/ExpGamingAdmin/locale/nl.cfg @@ -0,0 +1,15 @@ +[ExpGamingAdmin] +name=Admin Commands +tooltip=Admin Commands kan je hier vinden. +no-info-file=Infobestand niet gevonden. +message=Selecteer een speler en de bijbehorende actie. Wees er zeker van dat je de correcte actie kiest. +warning=Fout: Je kan de rank van deze speler niet aanpassen omdat het jouw rank overtreft. +short-reason=Fout: De reden is te kort. (Warning: The reason is too short. UPDATE) +rank-high=Fout: Deze speler overtreft jouw rank. +invalid=Fout: De speler kan niet gevonden worden en/of de actie is onjuist. Probeer opnieuw! +take-action=Actie ondernemen +tooltip-ban=Ban speler +tooltip-kick=Kick speler +tooltip-jail=Jail speler +tooltip-go-to=Ga naar speler +tooltip-bring=Breng speler diff --git a/modules/ExpGamingAdmin/locale/sv-SE.cfg b/modules/ExpGamingAdmin/locale/sv-SE.cfg new file mode 100644 index 00000000..679188c2 --- /dev/null +++ b/modules/ExpGamingAdmin/locale/sv-SE.cfg @@ -0,0 +1,19 @@ +[ExpGamingAdmin] +name=Adminkommandon +tooltip=Adminkommando gör dit hem här +no-info-file=Ingen informationsfil kunde hittas +message=Var snäll och välj en spelare och en åtgärd att utfärda, se till att du väljer den rätta! +warning=Warning: Den här spelaren har högre rang än dig. Därför kan du inte redigera dess rang. +short-reason=Warning: Skälet är för kort. +rank-high=Warning: Den här spelaren har högre rang än dig. Därför kan du inte redigera dess rang. +invalid=Spelaren eller åtgärden är ogiltig. Var vänlig och försök igen! +take-action=Utför åtgärd. +tooltip-ban=Bannlys Spelare +tooltip-kick=Sparka Spelare +tooltip-jail=Fängsla Spelare +tooltip-go-to=Gå till Spelare +tooltip-bring=Hämta spelare +report=Rapportera Spelare +low-print=__1__ har blivit rapporterad av __2__ för: __3__ +high-print=__1__ har blivit rapporterad av __2__ för: __3__ +cant-report=Den här spelaren kan inte bli rapporterad. diff --git a/modules/ExpGamingAdmin/softmod.json b/modules/ExpGamingAdmin/softmod.json new file mode 100644 index 00000000..efeae92e --- /dev/null +++ b/modules/ExpGamingAdmin/softmod.json @@ -0,0 +1,37 @@ +{ + "name": "ExpGamingAdmin", + "version": "4.0.0", + "description": "A set of useful admin commands and functions that can be used by other modules.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Admin", + "ExpGaming", + "Set", + "Commands", + "Functions", + "Scripts", + "Useful" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "submodules": { + "ExpGamingAdmin": "4.0.0", + "ExpGamingAdmin.Ban": "4.0.0", + "ExpGamingAdmin.ClearInventory": "4.0.0", + "ExpGamingAdmin.Gui": "4.0.0", + "ExpGamingAdmin.Jail": "4.0.0", + "ExpGamingAdmin.Kick": "4.0.0", + "ExpGamingAdmin.Reports": "4.0.0", + "ExpGamingAdmin.Teleport": "4.0.0", + "ExpGamingAdmin.TempBan": "4.0.0", + "ExpGamingAdmin.Warnings": "4.0.0", + "ExpGamingAdmin.Commands": "4.0.0" + }, + "dependencies": { + "ExpGamingCore.Role": "?^4.0.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingCore.Server": "?^4.0.0", + "FactorioStdLib.Game": "^0.8.0" + } +} diff --git a/modules/ExpGamingBot/autoChat/control.lua b/modules/ExpGamingBot/autoChat/control.lua new file mode 100644 index 00000000..b56bc760 --- /dev/null +++ b/modules/ExpGamingBot/autoChat/control.lua @@ -0,0 +1,166 @@ +--- Sends messages in chat in response to other messages +-- @module ExpGamingBot.autoChat +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Game = require('FactorioStdLib.Game') +local Server = require('ExpGamingCore.Server') +local Role -- ExpGamingCore.Role@^4.0.0 + +-- Local Variables +-- lots of these are jokes, but some have uses + +-- white spaces removed and made into lower +-- these messages are sent only to the player +local messages = { + ['discord']={'ExpGamingBot-autoChat.discord'}, + ['expgaming']={'ExpGamingBot-autoChat.website'}, + ['website']={'ExpGamingBot-autoChat.website'}, + ['command']={'ExpGamingBot-autoChat.custom-commands'}, + ['commands']={'ExpGamingBot-autoChat.custom-commands'}, + ['softmod']={'ExpGamingBot-autoChat.softmod'}, + ['script']={'ExpGamingBot-autoChat.softmod'}, + ['link']={'ExpGamingBot-autoChat.links'}, + ['links']={'ExpGamingBot-autoChat.links'}, + ['loop']={'ExpGamingBot-autoChat.loops'}, + ['loops']={'ExpGamingBot-autoChat.loops'}, + ['rhd']={'ExpGamingBot-autoChat.lhd'}, + ['roundabout']={'ExpGamingBot-autoChat.loops'}, + ['roundabouts']={'ExpGamingBot-autoChat.loops'}, + ['redmew']={'ExpGamingBot-autoChat.redmew'}, + ['afk']=function(_player) local max=_player for _,player in pairs(game.connected_players) do if max.afk_time < player.afk_time then max=player end end return {'ExpGamingBot-autoChat.afk',max.name,tick_to_display_format(max.afk_time)} end +} +-- white spaces removed and made into lower +-- these are global chat commands that can be used +-- commands start with ! (all messages are also commands) +local command_syntax = '!' +local commands = { + ['online']=function() return {'ExpGamingBot-autoChat.players-online',#game.connected_players} end, + ['playtime']=function() return {'ExpGamingBot-autoChat.map-time',tick_to_display_format(game.tick)} end, + ['players']=function() return {'ExpGamingBot-autoChat.players',#game.players} end, + ['dev']={'ExpGamingBot-autoChat.not-real-dev'}, + ['blame']=function(player) local names = {'Cooldude2606','arty714','badgamernl',player.name} return {'ExpGamingBot-autoChat.blame',names[math.random(#names)]} end, + ['readme']={'ExpGamingBot-autoChat.read-readme'}, + ['magic']={'ExpGamingBot-autoChat.magic'}, + ['aids']={'ExpGamingBot-autoChat.aids'}, + ['riot']={'ExpGamingBot-autoChat.riot'}, + ['lenny']={'ExpGamingBot-autoChat.lenny'}, + ['feedback']={'ExpGamingBot-autoChat.feedback'}, + ['wiki']={'ExpGamingBot-autoChat.wiki'}, + ['hodor']=function() local options = {'?','.','!','!!!'} return {'ExpGamingBot-autoChat.hodor',options[math.random(#options)]} end, + ['evolution']=function() return {'ExpGamingBot-autoChat.current-evolution',string.format('%.2f',game.forces['enemy'].evolution_factor)} end, + --Jokes about food and drink + ['whattoeat']={'ExpGamingBot-autoChat.food'}, + + ['makepopcorn']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data=player.name + }:on_event('timeout',function(self) + if self.data then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.get-popcorn-2',self.data}} end + end):open() return {'ExpGamingBot-autoChat.get-popcorn-1'} end, + + ['orderpizza']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data={player.name,0}, reopen=true + }:on_event('timeout',function(self) + if self.data[2]==0 then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.order-pizza-2',self.data[1]}} + elseif self.data[2]==1 then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.order-pizza-3',self.data[1]}} self.reopen = false + end + self.data[2]=self.data[2]+1 + end):open() return {'ExpGamingBot-autoChat.order-pizza-1'} end, + + ['passsomesnaps']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data={player.name,0}, reopen=true + }:on_event('timeout',function(self) + if self.data[2]==0 then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.get-snaps-2',self.data[1]}} + elseif self.data[2]==1 then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.get-snaps-3',self.data[1]}} self.reopen = false + end + self.data[2]=self.data[2]+1 + end):open() return {'ExpGamingBot-autoChat.get-snaps-1'} end, + + ['makecocktail']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data={player.name,0}, reopen=true + }:on_event('timeout',function(self) + if self.data[2]==0 then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.get-cocktail-2',self.data[1]}} + elseif self.data[2]==1 then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.get-cocktail-3',self.data[1]}} self.reopen = false + end + self.data[2]=self.data[2]+1 + end):open() return {'ExpGamingBot-autoChat.get-cocktail-1'} end, + + ['makecoffee']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data=player.name + }:on_event('timeout',function(self) + if self.data then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.make-coffee-2',self.data}} end + end):open() return {'ExpGamingBot-autoChat.make-coffee-1'} end, + + ['orderpizza']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data={player.name,0}, reopen=true + }:on_event('timeout',function(self) + if self.data[2]==0 then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.order-pizza-2',self.data[1]}} + elseif self.data[2]==1 then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.order-pizza-3',self.data[1]}} self.reopen = false + end + self.data[2]=self.data[2] + 1 + end):open() return {'ExpGamingBot-autoChat.order-pizza-1'} end, + + ['maketea']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data=player.name + }:on_event('timeout',function(self) + if self.data then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.make-tea-2',self.data}} end + end):open() return {'ExpGamingBot-autoChat.make-tea-1'} end, + + ['popcorn']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data=player.name + }:on_event('timeout',function(self) + if self.data then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.get-popcorn-2',self.data}} end + end):open() return {'ExpGamingBot-autoChat.get-popcorn-1'} end, + + ['meadplease']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data=player.name + }:on_event('timeout',function(self) + if self.data then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.get-mead-2',self.data}} end + end):open() return {'ExpGamingBot-autoChat.get-mead-1'} end, + + ['passabeer']=function(player) Server.new_thread{ + timeout=math.floor(180*(math.random()+0.5)),data=player.name + }:on_event('timeout',function(self) + if self.data then game.print{'ExpGamingBot-autoChat.message',{'ExpGamingBot-autoChat.get-beer-2',self.data}} end + end):open() return {'ExpGamingBot-autoChat.get-beer-1'} end +} + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + end +} + +-- Event Handlers Define +script.on_event(defines.events.on_console_chat,function(event) + local player = Game.get_player(event) + if not player then return end + local player_message = event.message:lower():gsub("%s+", "") + local allowed = Role and Role.allowed(player,'global-chat') or player.admin + for to_find,message in pairs(messages) do + if player_message:match(command_syntax..to_find) then + if allowed then + if is_type(message,'function') then message=message(player) end + game.print{'ExpGamingBot-autoChat.message',message} + else player_return({'ExpGamingBot-autoChat.rank-error'},nil,player) end + elseif player_message:match(to_find) then + if is_type(message,'function') then message=message(player) end + if not allowed then player_return({'ExpGamingBot-autoChat.message',message},nil,player) end + end + end + for to_find,message in pairs(commands) do + if player_message:match(command_syntax..to_find) then + if allowed then + if is_type(message,'function') then message=message(player) end + game.print{'ExpGamingBot-autoChat.message',message} + else player_return({'ExpGamingBot-autoChat.rank-error'},nil,player) end + end + end +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/ExpGamingBot/autoChat/locale/de.cfg b/modules/ExpGamingBot/autoChat/locale/de.cfg new file mode 100644 index 00000000..32fea59f --- /dev/null +++ b/modules/ExpGamingBot/autoChat/locale/de.cfg @@ -0,0 +1,20 @@ +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=You cant use global chat commands +players-online=There are __1__ players online +players=There have been __1__ players on this map +map-time=This map has been on for __1__ +line-8=Type /help for more info +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) +not-real-dev=Cooldude2606 is a dev for this server and makes the softmod (look top left) and is not a factorio dev. +softmod=A softmod is a custom scenario that runs on this server, example is the player list. +blame=Blame __1__ for what just happend! +afk=Your afk? Look at __1__ they have been afk for: __2__ +links=To see links open the readme and click links. +magic=Fear the admin magic (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) \ No newline at end of file diff --git a/modules/ExpGamingBot/autoChat/locale/en.cfg b/modules/ExpGamingBot/autoChat/locale/en.cfg new file mode 100644 index 00000000..4afb021d --- /dev/null +++ b/modules/ExpGamingBot/autoChat/locale/en.cfg @@ -0,0 +1,48 @@ +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=You can't use global chat commands +players-online=There are __1__ players online +players=There have been __1__ players on this map +map-time=This map has been on for __1__ +line-8=Type /help for more info +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: https://www.explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (It can be found through the question mark on the top left) +not-real-dev=Cooldude2606 is a dev for this server and makes the softmod (look top left) and is not a factorio dev. +softmod=A softmod is a custom scenario that runs on this server, example is the player list. +redmew=We dont talk about redmew here; they beat us to 1000 members; F +blame=Blame __1__ for what just happend! +afk=Your afk? Look at __1__, that player has been afk for: __2__ +links=To see links open the readme and click links. +current-evolution=Current evolution factor is __1__ +magic=Fear the admin magic (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) +loops=NO LOOPS; LOOPS ARE BAD; JUST NO LOOPS!!!!!; IF YOU MAKE A LOOP.... IT WILL NOT END WELL!!!!!!! +lenny=( ͡° ͜ʖ ͡°) +make-tea-1= ☕ Boiling the water... ☕ +make-tea-2= ☕ __1__ your tea is done! ☕ +order-pizza-1= 🍕 Finding nearest pizza supplier... 🍕 +order-pizza-2= 🍕 Figuring out the favourite pizza of __1__ 🍕 +order-pizza-3= 🍕 __1__ your pizza is here! 🍕 +make-coffee-1= ☕ Boiling the water and grinding the coffee beans... ☕ +make-coffee-2= ☕ __1__ we ran out of coffe beans! Have some tea instead. ☕ +get-beer-1= 🍺 Pouring A Glass 🍺 +get-beer-2= 🍻 Chears Mate 🍻 +get-mead-1= Filling the drinking horn +get-mead-2= Skål! +get-snaps-1=Pouring the glasses and finding the correct song book... +get-snaps-2=Singing a song...🎤🎶 +get-snaps-3=skål, my friends! +get-cocktail-1= 🍸 Inintiating mind reading unit... 🍸 +get-cocktail-2= 🍸 Mixing favourite ingredients of __1__ 🍸 +get-cocktail-3=🍸 __1__ your cocktail is done.🍸 +lhd=All trains must be LHD! +food=Don't know what to make for dinner? Use a random recipe from the random dinner suggestion generator at http://www.whatthefuckshouldimakefordinner.com/ +get-popcorn-1=Heating the oil and waiting for the popping sound... +get-popcorn-2=__1__ your popcorn is finished. Lean backwards and watch the drama unfold. +wiki=You can get more information about us and the custom scenario from our wiki: https://wiki.explosivegaming.nl/ +feedback=Do you have feedback? leave it at https://exp.fider.io/ +hodor=Hodor \ No newline at end of file diff --git a/modules/ExpGamingBot/autoChat/locale/fr.cfg b/modules/ExpGamingBot/autoChat/locale/fr.cfg new file mode 100644 index 00000000..32fea59f --- /dev/null +++ b/modules/ExpGamingBot/autoChat/locale/fr.cfg @@ -0,0 +1,20 @@ +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=You cant use global chat commands +players-online=There are __1__ players online +players=There have been __1__ players on this map +map-time=This map has been on for __1__ +line-8=Type /help for more info +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) +not-real-dev=Cooldude2606 is a dev for this server and makes the softmod (look top left) and is not a factorio dev. +softmod=A softmod is a custom scenario that runs on this server, example is the player list. +blame=Blame __1__ for what just happend! +afk=Your afk? Look at __1__ they have been afk for: __2__ +links=To see links open the readme and click links. +magic=Fear the admin magic (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) \ No newline at end of file diff --git a/modules/ExpGamingBot/autoChat/locale/nl.cfg b/modules/ExpGamingBot/autoChat/locale/nl.cfg new file mode 100644 index 00000000..32fea59f --- /dev/null +++ b/modules/ExpGamingBot/autoChat/locale/nl.cfg @@ -0,0 +1,20 @@ +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=You cant use global chat commands +players-online=There are __1__ players online +players=There have been __1__ players on this map +map-time=This map has been on for __1__ +line-8=Type /help for more info +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) +not-real-dev=Cooldude2606 is a dev for this server and makes the softmod (look top left) and is not a factorio dev. +softmod=A softmod is a custom scenario that runs on this server, example is the player list. +blame=Blame __1__ for what just happend! +afk=Your afk? Look at __1__ they have been afk for: __2__ +links=To see links open the readme and click links. +magic=Fear the admin magic (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) \ No newline at end of file diff --git a/modules/ExpGamingBot/autoChat/locale/sv-SE.cfg b/modules/ExpGamingBot/autoChat/locale/sv-SE.cfg new file mode 100644 index 00000000..98f81ad7 --- /dev/null +++ b/modules/ExpGamingBot/autoChat/locale/sv-SE.cfg @@ -0,0 +1,25 @@ + +[ExpGamingBot-autoChat] +message=[Chat Bot]: __1__ +rank-error=Du kan inte utföra globala chat-kommandon. +players-online=Det är __1__ spelare online +players=Det har varit __1__ spelare på den här kartan +map-time=Den här kartan har varit igång under __1__ +line-8=Type /help för mer information +join-us=Var snäll och förena dig med oss: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=Vi använder oss av specialiserade kommandon, som till exempel /tag och /report, se kommandotabben i readme för mer information. +read-readme=Se till att du har läst "Readme" (Finn den genom att klicka på frågetecknet högst upp i vänstra hörnet) +not-real-dev=Cooldude2606 är dev för den här servern och gör mjukmodden ("the softmod") och är inte en factorio dev. +ssoftmod=En mjukmod ("softmod") är ett specialscenario som används på den här servern, exempelvis listan över spelare. +blame=Skyll på __1__ för vad som just hände! +afk=Är du afk (borta från tangentbordet)? Titta på __1__, den spelaren har varit afk under: __2__ +links=För att se länkar, öppna readme och klicka "länkar". +magic=Frukta admin-magin (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆ +aids=≖ ‿ ≖Fear the aids of a public server ≖ ‿ ≖ +riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) +loops=INGA LOOPAR; LOOPAR ÄR DÅLIGT; JUST INGA LOOPAR!!!!!; OM DU GJÖR EN LOOP.... DET KOMMER INTE ATT SLUTA VÄL!!!!!!! +lhd=Alla tåg skall köras med vänstertrafik! +current-evolution=Nuvarande evolutionsfaktor är __1__ +wiki=Du kan få mer information om oss och scenariot på vår wiki: https://wiki.explosivegaming.nl/ \ No newline at end of file diff --git a/modules/ExpGamingBot/autoChat/softmod.json b/modules/ExpGamingBot/autoChat/softmod.json new file mode 100644 index 00000000..7c790178 --- /dev/null +++ b/modules/ExpGamingBot/autoChat/softmod.json @@ -0,0 +1,19 @@ +{ + "name": "ExpGamingBot.autoChat", + "version": "4.0.0", + "description": "Sends messages in chat based on what has been said by other players", + "location": "FSM_ARCHIVE", + "keywords": [ + "Chat", + "Bot", + "Jokes", + "Fun" + ], + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Server": "^4.0.0", + "ExpGamingCore.Role": "?^4.0.0" + }, + "collection": "ExpGamingBot@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingBot/autoMessage/control.lua b/modules/ExpGamingBot/autoMessage/control.lua new file mode 100644 index 00000000..b21a0f7c --- /dev/null +++ b/modules/ExpGamingBot/autoMessage/control.lua @@ -0,0 +1,74 @@ +--- Prints a message every 15 minutes to chat. +-- @module ExpGamingBot.autoMessage +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Server = require('ExpGamingCore.Server') +local Game = require('FactorioStdLib.Game') +local Role -- ExpGamingCore.Role@4.0.0 +local Sync -- ExpGamingCore.Sync@4.0.0 + +-- Local Variables + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + if loaded_modules['ExpGamingCore.Sync'] then Sync = require('ExpGamingCore.Sync') end + end, + on_post=function() + --code + end +} + +-- Event Handlers Define +script.on_init(function() + Server.new_thread{ + name='auto-message', + timeout=54000, -- 3240000 = 15 hours dont make the mistake i did, 54000 is 15 minutes + reopen=true, + data={ + high_role= 'Owner', + low_role= 'Regular', + low={ + {'ExpGamingBot-autoMessage.join-us'}, + {'ExpGamingBot-autoMessage.discord'}, + {'ExpGamingBot-autoMessage.website'}, + {'ExpGamingBot-autoMessage.custom-commands'}, + {'ExpGamingBot-autoMessage.read-readme'} + } + } + }:on_event('timeout',function(self) + local data = self.data + if not data.high_role or not data.low_role + or not data.low then self.reopen = false return end + game.print{'ExpGamingBot-autoMessage.message',{'ExpGamingBot-autoMessage.players-online',#game.connected_players}} + game.print{'ExpGamingBot-autoMessage.message',{'ExpGamingBot-autoMessage.map-time',tick_to_display_format(game.tick)}} + self.reopen = true + end):on_event(defines.events.on_player_joined_game,function(self,event) + local player = Game.get_player(event) + if not player then return end + local data = self.data + if not data.high_role or not data.low_role + or not data.low then self.reopen = false return end + if Role and Role.get_highest(player).index <= Role.get(data.low_role).index or player.admin then return end + for _,message in pairs(data.low) do + player_return({'ExpGamingBot-autoMessage.message',message},nil,player) + end + end):on_event('error',function(self,err) + if Sync then Sync.emit_embedded{ + title='Auto Message Error', + color=Color.to_hex(defines.textcolor.bg), + description='Auto Message Error - Closed Thread', + Error=err + } end + self.reopen = false + self:close() + end):open() +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/ExpGamingBot/autoMessage/locale/de.cfg b/modules/ExpGamingBot/autoMessage/locale/de.cfg new file mode 100644 index 00000000..49d19ede --- /dev/null +++ b/modules/ExpGamingBot/autoMessage/locale/de.cfg @@ -0,0 +1,9 @@ +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=There are __1__ players online +map-time=This map has been on for __1__ +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) \ No newline at end of file diff --git a/modules/ExpGamingBot/autoMessage/locale/en.cfg b/modules/ExpGamingBot/autoMessage/locale/en.cfg new file mode 100644 index 00000000..c67078a9 --- /dev/null +++ b/modules/ExpGamingBot/autoMessage/locale/en.cfg @@ -0,0 +1,9 @@ +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=There are __1__ players online +map-time=This map has been on for __1__ +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: https://www.explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (It can be found through the question mark on the top left) \ No newline at end of file diff --git a/modules/ExpGamingBot/autoMessage/locale/fr.cfg b/modules/ExpGamingBot/autoMessage/locale/fr.cfg new file mode 100644 index 00000000..49d19ede --- /dev/null +++ b/modules/ExpGamingBot/autoMessage/locale/fr.cfg @@ -0,0 +1,9 @@ +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=There are __1__ players online +map-time=This map has been on for __1__ +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) \ No newline at end of file diff --git a/modules/ExpGamingBot/autoMessage/locale/nl.cfg b/modules/ExpGamingBot/autoMessage/locale/nl.cfg new file mode 100644 index 00000000..49d19ede --- /dev/null +++ b/modules/ExpGamingBot/autoMessage/locale/nl.cfg @@ -0,0 +1,9 @@ +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=There are __1__ players online +map-time=This map has been on for __1__ +join-us=Please join us on: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=We use custom commands, such as /tag and /report, see the commands tab in readme for more info. +read-readme=Make sure you have read the Readme (can be found through the question mark on the top left) \ No newline at end of file diff --git a/modules/ExpGamingBot/autoMessage/locale/sv-SE.cfg b/modules/ExpGamingBot/autoMessage/locale/sv-SE.cfg new file mode 100644 index 00000000..f037d9df --- /dev/null +++ b/modules/ExpGamingBot/autoMessage/locale/sv-SE.cfg @@ -0,0 +1,10 @@ + +[ExpGamingBot-autoMessage] +message=[Chat Bot]: __1__ +players-online=Det är __1__ spelare online +map-time=Den här kartan har varit igång under __1__ +join-us=Var snäll och förena dig med oss: +discord=Discord: https://discord.explosivegaming.nl +website=Website: explosivegaming.nl +custom-commands=Vi använder oss av specialiserade kommandon, som till exempel /tag och /report, se kommandotabben i readme för mer information. +read-readme=Se till att du har läst "Readme" (Finn den genom att klicka på frågetecknet högst upp i vänstra hörnet) \ No newline at end of file diff --git a/modules/ExpGamingBot/autoMessage/softmod.json b/modules/ExpGamingBot/autoMessage/softmod.json new file mode 100644 index 00000000..769ab362 --- /dev/null +++ b/modules/ExpGamingBot/autoMessage/softmod.json @@ -0,0 +1,20 @@ +{ + "name": "ExpGamingBot.autoMessage", + "version": "4.0.0", + "description": "Prints a message every 15 minutes to chat.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Bot", + "Chat", + "Auto Message", + "Message" + ], + "dependencies": { + "ExpGamingCore.Server": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Role": "?^4.0.0", + "ExpGamingCore.Sync": "?^4.0.0" + }, + "collection": "ExpGamingBot@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingBot/discordAlerts/control.lua b/modules/ExpGamingBot/discordAlerts/control.lua new file mode 100644 index 00000000..a7069d21 --- /dev/null +++ b/modules/ExpGamingBot/discordAlerts/control.lua @@ -0,0 +1,63 @@ +--- Sends alerts to discord once there is a bot set up to read the alerts. +-- @module ExpGamingBot.discordAlerts@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Sync = require('ExpGamingCore.Sync') +local Color = require('FactorioStdLib.Color') +local Game = require('FactorioStdLib.Game') + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Event Handlers Define +script.on_event(defines.events.on_console_command,function(event) + local command = event.command + local args = {} + if event.parameters then for word in event.parameters:gmatch('%S+') do table.insert(args,word) end end + local data = {} + data.title = string.gsub(command,'^%l',string.upper) + data.by = event.player_index and game.players[event.player_index].name or '' + if data.by == '' then return end + if command == 'config' or command == 'banlist' then + Sync.emit_embedded{ + title='Edit To '..data.title, + color=Color.to_hex(defines.textcolor.bg), + description='A player edited the '..command..'.', + ['By:']=data.by, + ['Edit:']=table.concat(args,' ',1) + } + else + if command == 'ban' then + data.colour = Color.to_hex(defines.textcolor.crit) + data.reason = table.concat(args,' ',2) + elseif command == 'kick' then + data.colour = Color.to_hex(defines.textcolor.high) + data.reason = table.concat(args,' ',2) + elseif command == 'unban' then data.colour = Color.to_hex(defines.textcolor.low) + elseif command == 'mute' then data.colour = Color.to_hex(defines.textcolor.med) + elseif command == 'unmute' then data.colour = Color.to_hex(defines.textcolor.low) + elseif command == 'promote' then data.colour = Color.to_hex(defines.textcolor.info) + elseif command == 'demote' then data.colour = Color.to_hex(defines.textcolor.info) + elseif command == 'purge' then data.colour = Color.to_hex(defines.textcolor.med) + else return end + data.username = args[1] + if not Game.get_player(data.username) then return end + if string.sub(command,-1) == 'e' then data.command = command..'d' else data.command = command..'ed' end + data.reason = data.reason and data.reason ~= '' and data.reason or 'No Reason Required' + Sync.emit_embedded{ + title='Player '..data.title, + color=data.colour, + description='There was a player '..data.command..'.', + ['Player:']='<>'..data.username, + ['By:']='<>'..data.by, + ['Reason:']=data.reason + } + end +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/ExpGamingBot/discordAlerts/softmod.json b/modules/ExpGamingBot/discordAlerts/softmod.json new file mode 100644 index 00000000..1bcd1602 --- /dev/null +++ b/modules/ExpGamingBot/discordAlerts/softmod.json @@ -0,0 +1,20 @@ +{ + "name": "ExpGamingBot.discordAlerts", + "version": "4.0.0", + "description": "Sends alerts to discord once there is a bot set up to read the alerts.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Bot", + "Discord", + "Alerts", + "Messages", + "Acctions" + ], + "dependencies": { + "ExpGamingCore.Sync": "^4.0.0", + "FactorioStdLib.Color": "^0.8.0", + "FactorioStdLib.Game": "^0.8.0" + }, + "collection": "ExpGamingBot@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingBot/softmod.json b/modules/ExpGamingBot/softmod.json new file mode 100644 index 00000000..a7328e25 --- /dev/null +++ b/modules/ExpGamingBot/softmod.json @@ -0,0 +1,22 @@ +{ + "name": "ExpGamingBot", + "version": "4.0.0", + "description": "Different parts of a useful bot to help run a server. Discord Bot Not Included.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Discord", + "Bot", + "Messages", + "Chat", + "Auto" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "submodules": { + "ExpGamingBot.autoChat": "4.0.0", + "ExpGamingBot.autoMessage": "4.0.0", + "ExpGamingBot.discordAlerts": "4.0.0" + }, + "dependencies": {} +} diff --git a/modules/ExpGamingCommands/bonus/control.lua b/modules/ExpGamingCommands/bonus/control.lua new file mode 100644 index 00000000..e772de80 --- /dev/null +++ b/modules/ExpGamingCommands/bonus/control.lua @@ -0,0 +1,86 @@ +--- A full ranking system for factorio. +-- @module ExpGamingCommands.bonus@^4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local global = global{} +local Game = require('FactorioStdLib.Game') + +-- these are the settings which are changed with scale being as +100% +local settings = { + character_mining_speed_modifier=3, + character_crafting_speed_modifier=3, + character_running_speed_modifier=3, + character_build_distance_bonus=20, + character_reach_distance_bonus=20, + character_inventory_slots_bonus=200 +} + +--- Allows a player to set there bonus +-- @command bonus +-- @param bonus the amount of bonus there will get +commands.add_command('bonus', 'Set your player bonus (default is 20, guest has 0)', { + ['bonus'] = {true,'number-range-int',-1,50} -- -1 < math.floor(bonus) <= 50 +}, function(event,args) + local player = Game.get_player(event) + local bonus = args.bonus + for key,setting in pairs(settings) do player[key] = setting*math.floor(bonus)*0.01 end + global[player.index]=bonus + player_return('Bonus set to: '..math.floor(bonus)..'%') +end).default_admin_only = true + +script.on_event(defines.events.on_player_respawned,function(event) + local player = Game.get_player(event) + local bonus = global[player.index] + if bonus then + for key,setting in pairs(settings) do player[key] = setting*math.floor(bonus)*0.01 end + end +end) + +-- overridden by ExpGamingCore.Role if present +script.on_event(defines.events.on_pre_player_died,function(event) + local player = Game.get_player(event) + if player.admin then + player.ticks_to_respawn = 120 + -- manually dispatch death event because it is not fired when ticks_to_respawn is set pre death + Event.dispatch{ + name=defines.events.on_player_died, + tick=event.tick, + player_index=event.player_index, + cause = event.cause + } + end +end) + +return { + on_init= function(self) + if loaded_modules['ExpGamingCore.Role'] then + local Role = require('ExpGamingCore.Role') + -- instant respawn + script.on_event(defines.events.on_pre_player_died,function(event) + local player = Game.get_player(event) + if Role.allowed(player,'bonus-respawn') then + player.ticks_to_respawn = 120 + -- manually dispatch death event because it is not fired when ticks_to_respawn is set pre death + script.raise_event(defines.events.on_player_died,{ + name=defines.events.on_player_died, + tick=event.tick, + player_index=event.player_index, + cause = event.cause + }) + end + end) + -- either clears or adds default when rank changed + script.on_event(defines.events.role_change,function(event) + local player = Game.get_player(event) + if Role.allowed(player,'bonus') then + for key,setting in pairs(settings) do player[key] = setting*0.2 end + global[player.index]=20 + else + for key in pairs(settings) do player[key] = 0 end + global[player.index]=nil + end + end) + end + end +} \ No newline at end of file diff --git a/modules/ExpGamingCommands/bonus/softmod.json b/modules/ExpGamingCommands/bonus/softmod.json new file mode 100644 index 00000000..ddb09af9 --- /dev/null +++ b/modules/ExpGamingCommands/bonus/softmod.json @@ -0,0 +1,22 @@ +{ + "name": "ExpGamingCommands.bonus", + "version": "4.0.0", + "description": "Allows a bonus to be applied to players and instant respawn.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Instant Respawn", + "Bonus", + "Cheat", + "Commands", + "ExpGaming", + "Respawn" + ], + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingLib": "^4.0.0", + "ExpGamingCore.Command": "^4.0.0", + "ExpGamingCore.Role": "?^4.0.0" + }, + "collection": "ExpGamingCommands@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCommands/cheatMode/control.lua b/modules/ExpGamingCommands/cheatMode/control.lua new file mode 100644 index 00000000..19d05276 --- /dev/null +++ b/modules/ExpGamingCommands/cheatMode/control.lua @@ -0,0 +1,14 @@ +--- A full ranking system for factorio. +-- @module ExpGamingCommands.cheatMode@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +--- Toggles cheat mode for a player +-- @command cheat-mode +-- @param[opt] player the player to toggle if nil then the player using the command +commands.add_command('cheat-mode', 'Toggles cheat mode for a player', { + ['player']={false,'player'} +}, function(event,args) + local player = args.player or game.player + if player.cheat_mode == true then player.cheat_mode = false else player.cheat_mode = true end +end).default_admin_only = true diff --git a/modules/ExpGamingCommands/cheatMode/softmod.json b/modules/ExpGamingCommands/cheatMode/softmod.json new file mode 100644 index 00000000..cc2843f6 --- /dev/null +++ b/modules/ExpGamingCommands/cheatMode/softmod.json @@ -0,0 +1,19 @@ +{ + "name": "ExpGamingCommands.cheatMode", + "version": "4.0.0", + "description": "Adds a command which allow you to toggle cheatmode", + "location": "FSM_ARCHIVE", + "keywords": [ + "Cheat", + "Commands", + "Admin", + "ExpGaming", + "Cheat Mode", + "Hacks" + ], + "dependencies": { + "ExpGamingCore.Command": "^4.0.0" + }, + "collection": "ExpGamingCommands@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCommands/home/control.lua b/modules/ExpGamingCommands/home/control.lua new file mode 100644 index 00000000..d5c667fb --- /dev/null +++ b/modules/ExpGamingCommands/home/control.lua @@ -0,0 +1,47 @@ +--- A full ranking system for factorio. +-- @module ExpGamingCommands.home@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') +local global = global{} + +--- Sets the home for a player +-- @command set-home +commands.add_command('home', 'Allows you to set, remove and goto your homes', { + ['command'] = {false,'string-list',{'set','remove','goto','list','return'}}, + ['name'] = {false,'string-len',10} +}, function(event,args) + local player = Game.get_player(event) + if not global[player.index] then local spawn_pos = player.force.get_spawn_position(player.surface) global[player.index] = {Spawn={spawn_pos.x,spawn_pos.y},_m=3,_n=1,_r={spawn_pos.x,spawn_pos.y}} end + local homes = global[player.index] + local command = args.command + local name = args.name + if command == 'set' then + local pos = {math.floor(player.position.x),math.floor(player.position.y)} + if homes._n+1 > homes._m then player_return{'ExpGamingCommands-home.too-many-homes',homes._m} return commands.error end + homes[name] = pos + homes._n=homes._n+1 + player_return{'ExpGamingCommands-home.set',name,pos[1],pos[2]} + elseif command == 'remove' then + if not homes[name] then player_return{'ExpGamingCommands-home.invalid',name} end + homes[name] = nil + homes._n=homes._n-1 + player_return{'ExpGamingCommands-home.remove',name} + elseif command == 'goto' then + if not homes[name] then player_return{'ExpGamingCommands-home.invalid',name} end + local pos = {math.floor(player.position.x),math.floor(player.position.y)} + player.teleport(player.surface.find_non_colliding_position('player',homes[name],32,1),player.surface) + homes._r = pos + player_return{'ExpGamingCommands-home.goto',name} + elseif command == 'return' then + local pos = {math.floor(player.position.x),math.floor(player.position.y)} + player.teleport(player.surface.find_non_colliding_position('player',homes._r,32,1),player.surface) + homes._r = pos + player_return{'ExpGamingCommands-home.return',pos[1],pos[2]} + else + player_return{'ExpGamingCommands-home.homes',homes._n,homes._m} + local index = 1 + for home_name,pos in pairs(homes) do if home_name ~= '_n' and home_name ~= '_r' and home_name ~= '_m' then player_return{'ExpGamingCommands-home.home',index,home_name,pos[1],pos[2]} index=index+1 end end + end +end) diff --git a/modules/ExpGamingCommands/home/locale/en.cfg b/modules/ExpGamingCommands/home/locale/en.cfg new file mode 100644 index 00000000..e70a2161 --- /dev/null +++ b/modules/ExpGamingCommands/home/locale/en.cfg @@ -0,0 +1,9 @@ +[ExpGamingCommands-home] +too-many-homes=You have too many homes, to add more you must remove one. Your max is __1__. +homes=Your Homes: (__1__/__2__) +home=__1__) __2__: __3__ , __4__ +set=Your home "__1__" as been set to __2__ , __3__ +remove=Your home "__1__" as been removed +goto=You are now at "__1__" +return=You are now at your previous location: __1__ , __2__ +invalid=Invalid name, __1__ \ No newline at end of file diff --git a/modules/ExpGamingCommands/home/softmod.json b/modules/ExpGamingCommands/home/softmod.json new file mode 100644 index 00000000..72d2c368 --- /dev/null +++ b/modules/ExpGamingCommands/home/softmod.json @@ -0,0 +1,20 @@ +{ + "name": "ExpGamingCommands.home", + "version": "4.0.0", + "description": "Allows players to set homes and then return to them later.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Teleport", + "ExpGaming", + "Home", + "Return", + "Set Home", + "Commands" + ], + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Command": "^4.0.0" + }, + "collection": "ExpGamingCommands@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCommands/kill/control.lua b/modules/ExpGamingCommands/kill/control.lua new file mode 100644 index 00000000..b04ef3d8 --- /dev/null +++ b/modules/ExpGamingCommands/kill/control.lua @@ -0,0 +1,18 @@ +--- A full ranking system for factorio. +-- @module ExpGamingCommands.kill@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') + +--- Kills a player of a lower rank +-- @command kill +-- @param player the player to be killed +commands.add_command('kill', 'Kills a player. No player name kills yourself.', { + ['player']={false,'player-rank-alive'} +}, function(event,args) + local _player = Game.get_player(event) + local player = args.player + if player then player.character.die() + else _player.character.die() end +end).default_admin_only = true diff --git a/modules/ExpGamingCommands/kill/softmod.json b/modules/ExpGamingCommands/kill/softmod.json new file mode 100644 index 00000000..989c03ee --- /dev/null +++ b/modules/ExpGamingCommands/kill/softmod.json @@ -0,0 +1,21 @@ +{ + "name": "ExpGamingCommands.kill", + "version": "4.0.0", + "description": "Adds a command which can be used to kill a player or yourself.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Command", + "ExpGaming", + "Kill", + "Death", + "Admin", + "Tool" + ], + "dependencies": { + "ExpGamingCore.Command": "^4.0.0", + "ExpGamingCore.Role": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0" + }, + "collection": "ExpGamingCommands@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCommands/repair/control.lua b/modules/ExpGamingCommands/repair/control.lua new file mode 100644 index 00000000..be84b7f0 --- /dev/null +++ b/modules/ExpGamingCommands/repair/control.lua @@ -0,0 +1,68 @@ +--- A full ranking system for factorio. +-- @module ExpGamingCommands.repair@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + + +local Game = require('FactorioStdLib.Game') +local Role = require('ExpGamingCore.Role') + +-- Set an item to true to disallow it from being repaired +local disallow = { + ['loader']=true, + ['fast-loader']=true, + ['express-loader']=true, + ['electric-energy-interface']=true, + ['infinity-chest']=true +} + +-- Given const = 100: admin+ has unlimited, admin has const (100), mod has const / 2 (50), member has const / 5 (20) +local const = 100 +local repairDisallow + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init = function(self) + if loaded_modules['ExpGamingAdmin.TempBan'] then verbose('ExpGamingAdmin.TempBan is installed; Loading tempban src') repairDisallow = require(module_path..'/src/tempban') end + end +} + +--- Used so that the value can be overridden if tempban is present +-- @local +-- @function repairDisallow +-- @param player the player who called the command +-- @param entity the entity which was repaired +repairDisallow = function(player,entity) + player_return('You have repaired: '..entity.name..' this item is not allowed.',defines.textcolor.crit,player) + entity.destroy() +end + +--- Used to repair and heal items in an area, different ranks get different size areas +-- @command repair +-- @param range the range that items are repaired in +commands.add_command('repair', 'Repairs all destroyed and damaged entities in an area.', { + ['range']={true,'number-int'} +}, function(event,args) + local range = args.range + local player = Game.get_player(event) + local role = Role.get_highest(player) + local highest_admin_power = Role.meta.groups.Admin.highest-1 + local max_range = role.index-highest_admin_power > 0 and const/(role.index-highest_admin_power) or nil + local center = player and player.position or {x=0,y=0} + if not range or max_range and range > max_range then player_return({'ExpGamingCore_Command.invalid-range',0,math.floor(max_range)}) return commands.error end + local area = {{center.x-range,center.y-range},{center.x+range,center.y+range}} + local max_time_to_live = 2^32 - 1 + local sq_range = range^2 + for key, entity in pairs(player.surface.find_entities_filtered({area=area,type='entity-ghost'})) do + if entity.force == player.force and (entity.position.x-center.x)^2+(entity.position.y-center.y)^2 < sq_range then + if disallow[entity.ghost_prototype.name] then repairDisallow(player,entity) + elseif entity.time_to_live ~= max_time_to_live then entity.revive() end + end + end + for key, entity in pairs(player.surface.find_entities(area)) do + if entity.force == player.force and (entity.position.x-center.x)^2+(entity.position.y-center.y)^2 < sq_range and entity.health then entity.health = 10000 end + end +end).default_admin_only = true + +return ThisModule diff --git a/modules/ExpGamingCommands/repair/softmod.json b/modules/ExpGamingCommands/repair/softmod.json new file mode 100644 index 00000000..db6cbfab --- /dev/null +++ b/modules/ExpGamingCommands/repair/softmod.json @@ -0,0 +1,22 @@ +{ + "name": "ExpGamingCommands.repair", + "version": "4.0.0", + "description": "Allows items to be healed and repaired with a command", + "location": "FSM_ARCHIVE", + "keywords": [ + "ExpGaming", + "Command", + "Heal", + "Repair", + "Ghosts", + "Revive" + ], + "dependencies": { + "ExpGamingLib": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Role": "^4.0.0", + "ExpGamingAdmin.TempBan": "?^4.0.0" + }, + "collection": "ExpGamingCommands@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCommands/repair/src/tempban.lua b/modules/ExpGamingCommands/repair/src/tempban.lua new file mode 100644 index 00000000..31c029c2 --- /dev/null +++ b/modules/ExpGamingCommands/repair/src/tempban.lua @@ -0,0 +1,7 @@ +-- not_luadoc=true +local temp_ban = require('ExpGamingAdmin').temp_ban +return function(player,entity) + player_return('You have repaired: '..entity.name..' this item is not allowed.',defines.textcolor.crit,player) + temp_ban(player,'','Attempt To Repair A Banned Item') + entity.destroy() +end \ No newline at end of file diff --git a/modules/ExpGamingCommands/softmod.json b/modules/ExpGamingCommands/softmod.json new file mode 100644 index 00000000..6cfb5d37 --- /dev/null +++ b/modules/ExpGamingCommands/softmod.json @@ -0,0 +1,25 @@ +{ + "name": "ExpGamingCommands", + "version": "4.0.0", + "description": "A Collection of all of the custom commands used on ExpGaming servers.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Commands", + "ExpGaming", + "Admin", + "Tools" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "submodules": { + "ExpGamingCommands.bonus": "4.0.0", + "ExpGamingCommands.cheatMode": "4.0.0", + "ExpGamingCommands.home": "4.0.0", + "ExpGamingCommands.kill": "4.0.0", + "ExpGamingCommands.repair": "4.0.0", + "ExpGamingCommands.tags": "4.0.0", + "ExpGamingCommands.teleport": "4.0.0" + }, + "dependencies": {} +} diff --git a/modules/ExpGamingCommands/tags/control.lua b/modules/ExpGamingCommands/tags/control.lua new file mode 100644 index 00000000..f320144b --- /dev/null +++ b/modules/ExpGamingCommands/tags/control.lua @@ -0,0 +1,45 @@ +--- A full ranking system for factorio. +-- @module ExpGamingCommands@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') +local Role -- ExpGamingCore.Role@^4.0.0 + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + end +} + +--- Gives you a tag +-- @command tag +-- @param tag the tag you want to have +commands.add_command('tag', 'Give yourself a custom tag. Use "" to have more than one word.', { + ['tag'] = {true,'string-len',20} +}, function(event,args) + local player = Game.get_player(event) + if Role then + local role = Role.get_highest(player) + player.tag = role.tag..' - '..args.tag + else player.tag = args.tag end + player_return('Your tag has been set. Use /tag-clear to remove your tag') +end) + +--- Gives you a tag +-- @command tag +-- @param tag the tag you want to have +commands.add_command('tag-clear', 'Removes a custom tag.', { + ['player'] = {false,'player-rank'} +}, function(event,args) + local player = args.player or game.player + if Role then + local role = Role.get_highest(player) + player.tag = role.tag + else player.tag = '' end + player_return('Your tag has been removed.') +end) + +return ThisModule \ No newline at end of file diff --git a/modules/ExpGamingCommands/tags/softmod.json b/modules/ExpGamingCommands/tags/softmod.json new file mode 100644 index 00000000..ae4843ee --- /dev/null +++ b/modules/ExpGamingCommands/tags/softmod.json @@ -0,0 +1,20 @@ +{ + "name": "ExpGamingCommands.tags", + "version": "4.0.0", + "description": "Allows tags to be used by users.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Tags", + "Custom Tags", + "Commands", + "ExpGaming" + ], + "dependencies": { + "ExpGamingLib": "^4.0.0", + "ExpGamingCore.Role": "?^4.0.0", + "ExpGamingCore.Command": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0" + }, + "collection": "ExpGamingCommands@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCommands/teleport/control.lua b/modules/ExpGamingCommands/teleport/control.lua new file mode 100644 index 00000000..d66f7e1b --- /dev/null +++ b/modules/ExpGamingCommands/teleport/control.lua @@ -0,0 +1,35 @@ +--- A full ranking system for factorio. +-- @module ExpGamingCommands.teleport@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Admin = require('ExpGamingAdmin') + +--- Teleports the user to the player given +-- @command go-to +-- @param player player to go to +commands.add_command('go-to', 'Go to a player\'s location', { + ['player']={true,'player-online'} +}, function(event,args) + Admin.go_to(args.player,event) +end) + +--- Teleports a player to the user +-- @command bring +-- @param player player to go to +commands.add_command('bring', 'Bring a player to your location', { + ['player']={true,'player-online'} +}, function(event,args) + Admin.bring(args.player,event) +end) + +--- Teleports one player to another +-- @command tp +-- @param player_one the player that is teleported +-- @param player_two the player who is the destination +commands.add_command('tp', 'Teleport a player to another player\'s location', { + ['player_one']={true,'player-online'}, + ['player_two']={true,'player-online'} +}, function(event,args) + Admin.tp(args.player_one,args.player_two) +end) diff --git a/modules/ExpGamingCommands/teleport/softmod.json b/modules/ExpGamingCommands/teleport/softmod.json new file mode 100644 index 00000000..4420b19c --- /dev/null +++ b/modules/ExpGamingCommands/teleport/softmod.json @@ -0,0 +1,23 @@ +{ + "name": "ExpGamingCommands.teleport", + "version": "4.0.0", + "description": "Adds a few commands used to teleport players.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Teleport", + "Tp", + "Bring", + "GoTo", + "ExpGaming", + "Command", + "Admin", + "Tools" + ], + "dependencies": { + "ExpGamingCore.Command": "^4.0.0", + "ExpGamingAdmin.Teleport": "^4.0.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingCommands@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCore/Command/control.lua b/modules/ExpGamingCore/Command/control.lua new file mode 100644 index 00000000..70b23fed --- /dev/null +++ b/modules/ExpGamingCore/Command/control.lua @@ -0,0 +1,298 @@ +--- Command system that allows middle ware and auto validation of command arguments. +-- @module ExpGamingCore.Command@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias commands + +local Game = require('FactorioStdLib.Game') +local Color = require('FactorioStdLib.Color') + +--- Used as an error constant for validation +-- @field commands.error +-- @usage return commands.error, 'err message' +-- @usage return commands.error('err message') +commands.error = setmetatable({},{__call=function(...) return ... end}) +commands._add_command = commands.add_command +local commandDataStore = {} +local middleware = {} + +--- Used to add middle ware to the command handler, functions should return true or false +-- @tparam function callback function(player,commandName,event) should return true to allow next middle ware to run +function commands.add_middleware(callback) if not is_type(callback,'function') then error('Callback is not a function',2) return end table.insert(middleware,callback) end + +--- Index of all command data +-- @field commands.data +-- @usage commands.command_name -- returns command data +-- @usage commands.data -- returns all data +-- @tparam ?string|table|event key the command that will be returned: string is the name, table is the command data, event is event from add_command +-- @treturn table the command data +setmetatable(commands,{ + __index=function(tbl,key) return is_type(key,'table') and (key.command and rawget(commandDataStore,key.name) or key) or key == 'data' and commandDataStore or rawget(commandDataStore,key) end +}) + +--- Collection of functions that can be used to validate inputs +-- @table commands.validate +-- @usage commands.validate[type](value,event,...) +-- @tparam string type the type that the value should be +-- @param value the value that will be tested +-- @param ... any other data that can be passed to the function +-- @return[1] the validated value +-- @return[2] error constant +-- @return[2] the err message +-- @field __comment replace _ with - the ldoc did not like me using - in the names +-- @field string basically does nothing but a type filed is required +-- @field string_inf same as string but is infinite in length, must be last arg +-- @field string_len same as string but can define a max length +-- @field number converts the input into a number +-- @field number_int converts the input to a number and floors it +-- @field number_range allows a number in a range min < X <= max +-- @field number_range allows a number in a range after it has been floored min < math.floor(X) <= max +-- @field player converts the input into a valid player +-- @field player_online converts the input to a player if the player is online +-- @field player_alive converts the input to a player if the player is online and alive +-- @field player_role converts the input to a player if the player is a lower rank than the user or if the person is not admin and the user is +-- @field player_role-online converts the input to a player if the player is a lower rank than the user and online +-- @field player_role_alive converts the input to a player if the player is a lower rank than the user and online and alive +commands.validate = { + ['boolean']=function(value) value = value.lower() if value == 'true' or value == 'yes' or value == 'y' or value == '1' then return true else return false end end, + ['string']=function(value) return tostring(value) end, + ['string-inf']=function(value) return tostring(value) end, + ['string-list']=function(value,event,list) + local rtn = tostring(value) and table.includes(list,tostring(value)) and tostring(value) or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-string-list',table.concat(list,', ')} end return rtn end, + ['string-len']=function(value,event,max) + local rtn = tostring(value) and tostring(value):len() <= max and tostring(value) or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-string-len',max} end return rtn end, + ['number']=function(value) + local rtn = tonumber(value) or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-number'} end return rtn end, + ['number-int']=function(value) + local rtn = tonumber(value) and math.floor(tonumber(value)) or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-number'} end return rtn end, + ['number-range']=function(value,event,min,max) + local rtn = tonumber(value) and tonumber(value) > min and tonumber(value) <= max and tonumber(value) or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-number-range',min,max} end return rtn end, + ['number-range-int']=function(value,event,min,max) + local rtn = tonumber(value) and math.floor(tonumber(value)) > min and math.floor(tonumber(value)) <= max and math.floor(tonumber(value)) or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-number-range',min,max} end return rtn end, + ['player']=function(value) + local rtn = Game.get_player(value) or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-player',value} end return rtn end, + ['player-online']=function(value) + local player,err = commands.validate['player'](value) + if err then return commands.error(err) end + local rtn = player.connected and player or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-player-online'} end return rtn end, + ['player-alive']=function(value) + local player,err = commands.validate['player-online'](value) + if err then return commands.error(err) end + local rtn = player.character and player.character.health > 0 and player or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-player-alive'} end return rtn end, + ['player-rank']=function(value,event) + local player,err = commands.validate['player'](value) + if err then return commands.error(err) end + local rtn = player.admin and Game.get_player(event).admin and player or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-player-rank'} end return rtn end, + ['player-rank-online']=function(value) + local player,err = commands.validate['player-online'](value) + if err then return commands.error(err) end + local player,err = commands.validate['player-rank'](player) + if err then return commands.error(err) end return player end, + ['player-rank-alive']=function(value) + local player,err = commands.validate['player-alive'](value) + if err then return commands.error(err) end + local player,err = commands.validate['player-rank'](player) + if err then return commands.error(err) end return player end, +} +--- Adds a function to the validation list +-- @tparam string name the name of the validation +-- @tparam function callback function(value,event) which returns either the value to be used or commands.error{'error-message'} +function commands.add_validation(name,callback) if not is_type(callback,'function') then error('Callback is not a function',2) return end commands.validate[name]=callback end + +--- Returns the inputs of this command as a formated string +-- @usage commands.format_inputs('interface') -- returns (if you have ExpGamingCore.Server) +-- @tparam ?string|table|event command the command to get the inputs of +-- @treturn string the formated string for the inputs +function commands.format_inputs(command) + command = commands[command] + if not is_type(command,'table') then error('Command is not valid',2) end + local rtn = '' + for name,data in pairs(command.inputs) do + if data[1] == false then rtn=rtn..string.format('[%s] ',name) + else rtn=rtn..string.format('<%s> ',name) end + end + return rtn +end + +--- Used to validate the arguments of a command, will understand strings with "" as a single param else spaces divede the params +-- @usage commands.validate_args(event) -- returns args table +-- @tparam table event this is the event created by add_command not on_console_command +-- @treturn[1] table the args for this command +-- @return[2] command.error +-- @treturn string the error that happend while parsing the args +function commands.validate_args(event) + local command = commands[event.name] + if not is_type(command,'table') then error('Command not valid',2) end + local rtn = {} + local count = 0 + local count_opt = 0 + for _,data in pairs(command.inputs) do count = count + 1 if data[1] == false then count_opt = count_opt + 1 end end + -- checks that there is some args given if there is meant to be + if not event.parameter then + if count == count_opt then return rtn + else return commands.error('invalid-inputs') end + end + -- splits the args into words so that it can be used to assign values + local words = string.split(event.parameter,' ') + local index = 0 + for _,word in pairs(words) do + index = index+1 + if not word then break end + local pos, _pos = word:find('"') + local hasSecond = pos and word:find('"',pos+1) or nil + while not hasSecond and pos and pos == _pos do + local next = table.remove(words,index+1) + if not next then return commands.error('invalid-parse') end + words[index] = words[index]..' '..next + _pos = words[index]:find('"',pos+1) + end + end + -- assigns the values from the words to the args + index = 0 + for name,data in pairs(command.inputs) do + index = index+1 + local arg = words[index] + if not arg and data[1] then return commands.error('invalid-inputs') end + if data[2] == 'string-inf' then rtn[name] = table.concat(words,' ',index) break end + local valid = is_type(data[2],'function') and data[2] or commands.validate[data[2]] or error('Invalid validation ("'..tostring(data[2])..'") for command: "'..command.name..'/'..name..'"') + local temp_tbl = table.deepcopy(data) table.remove(temp_tbl,1) table.remove(temp_tbl,1) + local value, err = valid(arg,event,unpack(temp_tbl)) + if value == commands.error then return value, err end + rtn[name] = is_type(value,'string') and value:gsub('"','') or value + end + return rtn +end + +--- Used to return all the commands a player can use +-- @usage get_commands(1) -- return table of command data for each command that the player can use +-- @tparam ?index|name|player| player the player to test as +-- @treturn table a table containg all the commands the player can use +function commands.get_commands(player) + player = Game.get_player(player) + local commands = {} + if not player then return error('Invalid player',2) end + for name,data in pairs(commandDataStore) do + if #middleware > 0 then for _,callback in pairs(middleware) do + local success, err = pcall(callback,player,name,data) + if not success then error(err) + elseif err then table.insert(commands,data) end + end elseif data.default_admin_only == true and player.admin then table.insert(commands,data) end + end + return commands +end + +local function logMessage(player_name,command,message,args) + game.write_file('commands.log', + game.tick + ..' Player: "'..player_name..'"' + ..' '..message..': "'..command.name..'"' + ..' With args of: '..table.tostring(args) + ..'\n' + , true, 0) +end + +--- Used to call the custom commands +-- @usage You dont its an internal command +-- @tparam table command the event rasied by the command +local function run_custom_command(command) + local data = commands.data[command.name] + local player = Game.get_player(command) or SERVER + -- runs all middle ware if any, if there is no middle where then it relies on .default_admin_only + if #middleware > 0 then for _,callback in pairs(middleware) do + local success, err = pcall(callback,player,command.name,command) + if not success then error(err) + elseif not err then + player_return({'ExpGamingCore_Command.command-fail',{'ExpGamingCore_Command.unauthorized'}},defines.textcolor.crit) + logMessage(player.name,command,'Failed to use command (Unauthorized)',commands.validate_args(command)) + game.player.play_sound{path='utility/cannot_build'} + return + end + end elseif data.default_admin_only == true and player and not player.admin then + player_return({'ExpGamingCore_Command.command-fail',{'ExpGamingCore_Command.unauthorized'}},defines.textcolor.crit) + logMessage(player.name,command,'Failed to use command (Unauthorized)',commands.validate_args(command)) + game.player.play_sound{path='utility/cannot_build'} + return + end + -- gets the args for the command + local args, err = commands.validate_args(command) + if args == commands.error then + if is_type(err,'table') then table.insert(err,command.name) table.insert(err,commands.format_inputs(data)) + player_return({'ExpGamingCore_Command.command-fail',err},defines.textcolor.high) else player_return({'ExpGamingCore_Command.command-fail',{'ExpGamingCore_Command.invalid-inputs',command.name,commands.format_inputs(data)}},defines.textcolor.high) end + logMessage(player.name,command,'Failed to use command (Invalid Args)',args) + player.play_sound{path='utility/deconstruct_big'} + return + end + -- runs the command + local success, err = pcall(data.callback,command,args) + if not success then error(err) end + if err ~= commands.error and player ~= SERVER then player_return({'ExpGamingCore_Command.command-ran'},defines.textcolor.info) end + logMessage(player.name,command,'Used command',args) +end + +--- Used to define commands +-- @usage --see examples in file +-- @tparam string name the name of the command +-- @tparam[opt='No Description'] string description the description of the command +-- @tparam[opt=an infinite string] 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 callback the function to call on the event +commands.add_command = function(name, description, inputs, callback) + if commands[name] then error('That command is already registered',2) end + if not is_type(name,'string') then error('Command name has not been given') end + if not is_type(callback,'function') or not is_type(inputs,'table') then + if is_type(inputs,'function') then commands._add_command(name,description,inputs) + else error('Invalid args given to add_command') end + end + verbose('Created Command: '..name) + -- test for string and then test for locale string + description = is_type(description,'string') and description + or is_type(description,'table') and is_type(description[1],'string') and string.find(description[1],'.+[.].+') and {description,''} + or 'No Description' + inputs = is_type(inputs,'table') and inputs or {['param']={false,'string-inf'}} + commandDataStore[name] = { + name=name, + description=description, + inputs=inputs, + callback=callback, + admin_only=false + } + local help = is_type(description,'string') and commands.format_inputs(name)..'- '..description + or is_type(description,'table') and is_type(description[1],'string') and string.find(description[1],'.+[.].+') and {description,commands.format_inputs(name)..'- '} + or commands.format_inputs(name) + commandDataStore[name].help = help + commands._add_command(name,help,function(...) + local success, err = Manager.sandbox(run_custom_command,{},...) + if not success then error(err) end + end) + return commandDataStore[name] +end + +return commands + +--[[ + command example + + **locale file** + [foo] + description=__1__ this is a command + + **control.lua** + commands.add_command('foo',{'foo.description'},{ + ['player']={true,'player'}, -- a required arg that must be a valid player + ['number']={true,'number-range',0,10}, -- a required arg that must be a number 0 0 then + local update = 4 + if global.cam_index >= #global.cams then global.cam_index = 1 end + if update > #global.cams then update = #global.cams end + for cam_offset = 0,update do + local _cam = global.cams[global.cam_index+cam_offset] + if not _cam then break end + if not _cam.cam.valid then table.remove(global.cams,global.cam_index) + elseif not _cam.entity.valid then table.remove(global.cams,global.cam_index) + else _cam.cam.position = _cam.entity.position if not _cam.surface then _cam.cam.surface_index = _cam.entity.surface.index end global.cam_index = global.cam_index+1 + end + end + global.cam_index = global.cam_index+update + end +end) + +script.on_event('on_player_respawned',function(event) + if loaded_modules['ExpGamingCore.Server'] then return end + if global.players and is_type(global.players,'table') and #global.players > 0 and global.players[event.player_index] then + local remove = {} + local player = Game.get_player(event) + for index,cam in pairs(global.players[event.player_index]) do + if cam.valid then table.insert(global.cams,{cam=cam,entity=player.character,surface=player.surface}) + else table.insert(remove,index) end + end + for n,index in pairs(remove) do + table.remove(global.players[event.player_index],index-n+1) + end + end +end) + +function Gui:on_init() + if loaded_modules['ExpGamingCore.Server'] then + Server = require('ExpGamingCore.Server') + verbose('ExpGamingCore.Server is installed; Loading server src') + script.on_init(require(module_path..'/src/server',{Gui=self})) + end +end + +function Gui.on_post() + Gui.test = require(module_path..'/src/test',{Gui=Gui}) +end + + +return Gui \ No newline at end of file diff --git a/ExpCore/GuiParts/inputs.lua b/modules/ExpGamingCore/Gui/inputs/control.lua similarity index 67% rename from ExpCore/GuiParts/inputs.lua rename to modules/ExpGamingCore/Gui/inputs/control.lua index 73e249e1..54abfe48 100644 --- a/ExpCore/GuiParts/inputs.lua +++ b/modules/ExpGamingCore/Gui/inputs/control.lua @@ -1,17 +1,22 @@ ---[[ -Explosive Gaming +--- Adds a clean way of making new inputs for a gui allowing for sliders and text inputs to be hanndleded with custom events +-- @module ExpGamingCore.Gui.Inputs +-- @alias inputs +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE -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 -]] +--- This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module +-- @function _comment + +local Game = require('FactorioStdLib.Game') +local Color = require('FactorioStdLib.Color') +local mod_gui = require('mod-gui') +local Gui = require('ExpGamingCore.Gui') local inputs = {} -inputs._input = {} +inputs._prototype = {} -- these are just so you can have short cuts to this inputs.events = { - error='error', + --error={}, -- this is added after event calls are added as it is not a script event state=defines.events.on_gui_checked_state_changed, click=defines.events.on_gui_click, elem=defines.events.on_gui_elem_changed, @@ -25,10 +30,10 @@ inputs.events = { -- @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) +function inputs._prototype: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 + if event == inputs.events.error then self._error = callback return self end self.events[event] = callback return self end @@ -37,7 +42,7 @@ end -- @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) +function inputs._prototype:draw(root) local player = Game.get_player(root.player_index) if is_type(self.draw_data.caption,'string') and player.gui.is_valid_sprite_path(self.draw_data.caption) then local data = table.deepcopy(self.draw_data) @@ -73,8 +78,8 @@ function inputs._input:draw(root) local success, err = pcall(self.data._items,player,root) if success then data.items = err else error(err) end if is_type(self.data._index,'function') then - local success, err = pcall(self.data._index,player,root) - if success then data.selected_index = err else error(err) end + local _success, _err = pcall(self.data._index,player,root) + if _success then data.selected_index = _err else error(_err) end end return root.add(data) else @@ -82,46 +87,48 @@ function inputs._input:draw(root) end end ---- Add a new input, this is the same as doing frame.add{} but returns a diffrent object +--- Add a new input, this is the same as doing frame.add{} but returns a different object -- @usage Gui.inputs.add{type='button',name='test',caption='Test'} +-- @usage return_value(frame) -- draws the button onto that frame -- @tparam table obj the new element to add if caption is a sprite path then sprite is used --- @treturn table the custom input object +-- @treturn table the custom input object, calling the returned value will draw the button 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' or - type == 'drop-down' - then else return end + if type ~= 'button' + and type ~= 'sprite-button' + and type ~= 'choose-elem-button' + and type ~= 'checkbox' + and type ~= 'radiobutton' + and type ~= 'textfield' + and type ~= 'text-box' + and type ~= 'slider' + and type ~= 'drop-down' + then return end verbose('Created Input: '..obj.name..' ('..obj.type..')') 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) + setmetatable(obj,{__index=inputs._prototype,__call=function(self,...) return self:draw(...) end}) + Gui.data('inputs_'..type,obj.name,obj) return obj end -- this just runs the events given to inputs function inputs._event_handler(event) if not event.element then return end - local elements = Gui._get_data('inputs_'..event.element.type) or {} + local elements = Gui.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 {} + elements = Gui.data.inputs_button or {} element = elements[event.element.name] end if element then + verbose('There was a gui event ('..Event.names[event.name]..') with element: '..event.element.name) if not is_type(element.events[event.name],'function') then return end - local success, err = pcall(element.events[event.name],event) + local success, err = Manager.sandbox(element.events[event.name],{},event) if not success then if is_type(element._error,'function') then pcall(element._error) else error(err) end @@ -129,62 +136,57 @@ function inputs._event_handler(event) 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) -Event.register(inputs.events.slider,inputs._event_handler) -Event.register(inputs.events.selection,inputs._event_handler) +script.on_event(inputs.events,inputs._event_handler) +inputs.events.error = {} --- the folwing functions are just to make inputs easier but if what you want is not include use inputs.add(obj) +-- the following 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 +-- @param callbacks can either be a single function or a list of function pairs see examples 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{ + local rtn_button = inputs.add{ type='button', name=name, caption=display, tooltip=tooltip } - button.data._callbacks = callbacks - button:on_event('click',function(event) - local elements = Gui._get_data('inputs_'..event.element.type) or {} + rtn_button.data._callbacks = callbacks + rtn_button:on_event('click',function(event) + local elements = Gui.data['inputs_'..event.element.type] or {} local button = elements[event.element.name] if not button and event.element.type == 'sprite-button' then - elements = Gui._get_data('inputs_button') or {} + elements = Gui.data.inputs_button or {} button = elements[event.element.name] end 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 + local btn_callbacks = button.data._callbacks + if is_type(btn_callbacks,'function') then btn_callbacks = {{function() return true end,btn_callbacks}} end + for _,data in pairs(btn_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 + 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 end) - return button + return rtn_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 elem_type 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) +-- @tparam function callback 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{ @@ -195,7 +197,7 @@ function inputs.add_elem_button(name,elem_type,tooltip,callback) } button.data._callback = callback button:on_event('elem',function(event) - local button = Gui._get_data('inputs_'..event.element.type)[event.element.name] + local button = Gui.data['inputs_'..event.element.type][event.element.name] 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} @@ -210,27 +212,28 @@ 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) +-- @tparam boolean radio if this is a radio button +-- @tparam string display the display for this button, either text or sprite path +-- @tparam function default the callback which choses the default check state +-- @tparam function callback_true the callback to call when changed to true +-- @tparam function callback_false the callback to call when changed to false -- @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{ + local rtn_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 checkbox = Gui._get_data('inputs_'..event.element.type)[event.element.name] + if is_type(default,'function') then rtn_checkbox.data._state = default end + rtn_checkbox.data._true = callback_true + rtn_checkbox.data._false = callback_false + rtn_checkbox:on_event('state',function(event) + local checkbox = Gui.data['inputs_'..event.element.type][event.element.name] local player = Game.get_player(event) - local state = event.element.state - if state then + if event.element.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 @@ -242,17 +245,17 @@ function inputs.add_checkbox(name,radio,display,default,callback_true,callback_f else error('Invalid Callback') end end end) - return checkbox + return rtn_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. +--- Used to reset the state of radio buttons, recommended to be called on_state_change to reset any radio buttons it is meant 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 _elements = Gui.data['inputs_'..element.type] or {} local _element = _elements[element.name] local player = Game.get_player(element.player_index) local state = false @@ -263,7 +266,7 @@ function inputs.reset_radio(elements) end else if elements.valid then - local _elements = Gui._get_data('inputs_'..elements.type) or {} + local _elements = Gui.data['inputs_'..elements.type] or {} local _element = _elements[elements.name] local player = Game.get_player(elements.player_index) local state = false @@ -279,36 +282,36 @@ end -- @tparam string name the name of this button -- @tparam boolean box is it a text box rather than a text field -- @tparam string text the starting text --- @tparam function the callback to call on change function(player,text,element) +-- @tparam function callback the callback to call on change function(player,text,element) -- @treturn table the text object that was made, to allow a custom error event if wanted function inputs.add_text(name,box,text,callback) local type = 'textfield'; if box then type='text-box' end - local textbox = inputs.add{ + local rtn_textbox = inputs.add{ type=type, name=name, text=text } - textbox.data._callback = callback - textbox:on_event('text',function(event) - local textbox = Gui._get_data('inputs_'..event.element.type)[event.element.name] + rtn_textbox.data._callback = callback + rtn_textbox:on_event('text',function(event) + local textbox = Gui.data['inputs_'..event.element.type][event.element.name] local player = Game.get_player(event) local element = event.element - local callback = textbox.data._callback - if is_type(callback,'function') then - local success, err = pcall(callback,player,element.text,element) + local event_callback = textbox.data._callback + if is_type(event_callback,'function') then + local success, err = pcall(event_callback,player,element.text,element) if not success then error(err) end else error('Invalid Callback Condition Format') end end) - return textbox + return rtn_textbox end --- Used to define a slider callback only on value_changed -- @usage Gui.inputs.add_slider('test','horizontal',1,10,5,function) -- @tparam string name the name of this button --- @tapram string text the caption to go with the slider +-- @tparam string orientation direction of the slider -- @tparam number min the lowest number -- @tparam number max the highest number --- @param start_callback either a number or a function to return a number +-- @tparam function start_callback either a number or a function to return a number -- @tparam function callback the function to be called on value_changed function(player,value,percent,element) -- @treturn table the slider object that was made, to allow a custom error event if wanted function inputs.add_slider(name,orientation,min,max,start_callback,callback) @@ -323,7 +326,7 @@ function inputs.add_slider(name,orientation,min,max,start_callback,callback) slider.data._start = start_callback slider.data._callback = callback slider:on_event('slider',function(event) - local slider = Gui._get_data('inputs_'..event.element.type)[event.element.name] + local slider = Gui.data['inputs_'..event.element.type][event.element.name] local player = Game.get_player(event) local value = event.element.slider_value local data = slider.data @@ -338,35 +341,35 @@ end --- Used to define a drop down callback only on value_changed -- @usage Gui.inputs.add_drop_down('test',{1,2,3},1,function) +-- @tparam string name name of the drop down -- @param items either a list or a function which returns a list -- @param index either a number or a function which returns a number -- @tparam function callback the callback which is called when a new index is selected function(player,selected,items,element) -- @treturn table the drop-down object that was made, to allow a custom error event if wanted function inputs.add_drop_down(name,items,index,callback) - local drop_down = inputs.add{ + local rtn_dropdown = inputs.add{ type='drop-down', name=name, items=items, selected_index=index } - drop_down.data._items = items - drop_down.data._index = index - drop_down.data._callback = callback - drop_down:on_event('selection',function(event) - local drop_down = Gui._get_data('inputs_'..event.element.type)[event.element.name] + rtn_dropdown.data._items = items + rtn_dropdown.data._index = index + rtn_dropdown.data._callback = callback + rtn_dropdown:on_event('selection',function(event) + local dropdown = Gui.data['inputs_'..event.element.type][event.element.name] local player = Game.get_player(event) local element = event.element - local items = element.items - local selected = items[element.selected_index] - local callback = drop_down.data._callback - if is_type(callback,'function') then - local success, err = pcall(callback,player,selected,items,element) + local drop_items = element.items + local selected = drop_items[element.selected_index] + local drop_callback = dropdown.data._callback + if is_type(drop_callback,'function') then + local success, err = pcall(drop_callback,player,selected,drop_items,element) if not success then error(err) end else error('Invalid Callback Condition Format') end end) - return drop_down + return rtn_dropdown end -return inputs - --- to see examples look at GuiParts/test.lua +-- calling will attempt to add a new input +return setmetatable(inputs,{__call=function(self,...) return self.add(...) end}) diff --git a/modules/ExpGamingCore/Gui/inputs/softmod.json b/modules/ExpGamingCore/Gui/inputs/softmod.json new file mode 100644 index 00000000..ba17e5a2 --- /dev/null +++ b/modules/ExpGamingCore/Gui/inputs/softmod.json @@ -0,0 +1,23 @@ +{ + "name": "ExpGamingCore.Gui.inputs", + "version": "4.0.0", + "description": "Addds an event manager for gui inputs and easy input creation", + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Inputs", + "Buttons", + "Text Fields" + ], + "collection": "ExpGamingCore.Gui@4.0.0", + "dependencies": { + "mod-gui": "*", + "FactorioStdLib.Color": "^0.8.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Gui": "^4.0.0" + }, + "submodules": {} +} diff --git a/modules/ExpGamingCore/Gui/left/control.lua b/modules/ExpGamingCore/Gui/left/control.lua new file mode 100644 index 00000000..7de7a904 --- /dev/null +++ b/modules/ExpGamingCore/Gui/left/control.lua @@ -0,0 +1,245 @@ +--- Adds a organiser for left gui elements which will automatically update there information and have open requirements +-- @module ExpGamingCore.Gui.Left +-- @alias left +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +--- This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module +-- @function _comment +local Game = require('FactorioStdLib.Game') +local Server = require('ExpGamingCore.Server') +local Color = require('FactorioStdLib.Color') +local mod_gui = require('mod-gui') +local Gui = require('ExpGamingCore.Gui') +local order_config = require(module_path..'/order_config') +local Role -- this is optional and is handled by it being present, it is loaded on init + +local left = {} +left._prototype = {} + +left.hide = Gui.inputs{ + name='gui-left-hide', + type='button', + caption='<' +}:on_event('click',function(event) + for _,child in pairs(event.element.parent.children) do + if child.name ~= 'popups' then child.style.visible = false end + end +end) + +local global = global() + +-- used for debugging +function left.override_open(state) + global.over_ride_left_can_open = state +end +--- Used to add a left gui frame +-- @usage Gui.left.add{name='foo',caption='Foo',tooltip='just testing',open_on_join=true,can_open=function,draw=function} +-- @usage return_value(player) -- toggles visibility for that player, if no player then updates for all players +-- @param obj this is what will be made, needs a name and a draw function(root_frame), open_on_join can be used to set the default state true/false, can_open is a test to block it from opening but is not needed +-- @return the object that is made, calling the returned value with out a param will update the gui, else will toggle visibility for that player +function left.add(obj) + if not is_type(obj,'table') then return end + if not is_type(obj.name,'string') then return end + verbose('Created Left Gui: '..obj.name) + setmetatable(obj,{__index=left._prototype,__call=function(self,player) if player then return self:toggle(player) else return left.update(self.name) end end}) + Gui.data('left',obj.name,obj) + if Gui.toolbar then Gui.toolbar(obj.name,obj.caption,obj.tooltip,function(event) obj:toggle(event) end) end + return obj +end + +--- This is used to update all the guis of connected players, good idea to use our thread system as it as nested for loops +-- @usage Gui.left.update() +-- @tparam[opt] string frame this is the name of a frame if you only want to update one +-- @param[opt] players the player to update for, if not given all players are updated, can be one player +function left.update(frame,players) + if not Server or not Server._thread then + players = is_type(players,'table') and #players > 0 and {unpack(players)} or is_type(players,'table') and {players} or Game.get_player(players) and {Game.get_player(players)} or game.connected_players + for _,player in pairs(players) do + local frames = Gui.data.left or {} + if frame then frames = {[frame]=frames[frame]} or {} end + for _,left_frame in pairs(frames) do + if left_frame then left_frame:first_open(player) end + end + end + else + local frames = Gui.data.left or {} + if frame then frames = {[frame]=frames[frame]} or {} end + players = is_type(players,'table') and #players > 0 and {unpack(players)} or is_type(players,'table') and {players} or Game.get_player(players) and {Game.get_player(players)} or game.connected_players + Server.new_thread{ + data={players=players,frames=frames} + }:on_event('tick',function(thread) + if #thread.data.players == 0 then thread:close() return end + local player = table.remove(thread.data.players,1) + Server.new_thread{ + data={player=player,frames=thread.data.frames} + }:on_event('resolve',function(thread) + for _,left_frame in pairs(thread.data.frames) do + if left_frame then left_frame:first_open(thread.data.player) end + end + end):queue() + end):open() + end +end + +--- Used to open the left gui of every player +-- @usage Gui.left.open('foo') +-- @tparam string left_name this is the gui that you want to open +-- @tparam[opt] LuaPlayer the player to open the gui for +function left.open(left_name,player) + local players = player and {player} or game.connected_players + local _left = Gui.data.left[left_name] + if not _left then return end + if not Server or not Server._thread then + for _,next_player in pairs(players) do _left:open(next_player) end + else + Server.new_thread{ + data={players=players} + }:on_event('tick',function(thread) + if #thread.data.players == 0 then thread:close() return end + local next_player = table.remove(thread.data.players,1) + _left:open(next_player) + end):open() + end +end + +--- Used to close the left gui of every player +-- @usage Gui.left.close('foo') +-- @tparam string left_name this is the gui that you want to close +-- @tparam[opt] LuaPlayer the player to close the gui for +function left.close(left_name,player) + local players = player and {player} or game.connected_players + local _left = Gui.data.left[left_name] + if not _left then return end + if not Server or not Server._thread or player then + for _,next_player in pairs(players) do _left:close(next_player) end + else + Server.new_thread{ + data={players=players} + }:on_event('tick',function(thread) + if #thread.data.players == 0 then thread:close() return end + local next_player = table.remove(thread.data.players,1) + _left:close(next_player) + end):open() + end +end + + +--- Used to force the gui open for the player +-- @usage left:open(player) +-- @tparam luaPlayer player the player to open the gui for +function left._prototype:open(player) + player = Game.get_player(player) + if not player then error('Invalid Player') end + local left_flow = mod_gui.get_frame_flow(player) + if not left_flow[self.name] then self:first_open(player) end + left_flow[self.name].style.visible = true + if left_flow['gui-left-hide'] then left_flow['gui-left-hide'].style.visible = true end +end + +--- Used to force the gui closed for the player +-- @usage left:open(player) +-- @tparam luaPlayer player the player to close the gui for +function left._prototype:close(player) + player = Game.get_player(player) + if not player then error('Invalid Player') end + local left_flow = mod_gui.get_frame_flow(player) + if not left_flow[self.name] then self:first_open(player) end + left_flow[self.name].style.visible = false + local count = 0 + for _,child in pairs(left_flow.children) do if child.style.visible then count = count+1 end if count > 1 then break end end + if count == 1 and left_flow['gui-left-hide'] then left_flow['gui-left-hide'].style.visible = false end +end + +--- When the gui is first made or is updated this function is called, used by the script +-- @usage left:first_open(player) -- returns the frame +-- @tparam LuaPlayer player the player to draw the gui for +-- @treturn LuaFrame the frame made/updated +function left._prototype:first_open(player) + player = Game.get_player(player) + local left_flow = mod_gui.get_frame_flow(player) + local frame + if left_flow[self.name] then + frame = left_flow[self.name] + frame.clear() + else + if not left_flow['gui-left-hide'] then left.hide(left_flow).style.maximal_width=15 end + frame = left_flow.add{type='frame',name=self.name,style=mod_gui.frame_style,caption=self.caption,direction='vertical'} + frame.style.visible = false + if is_type(self.open_on_join,'boolean') then frame.style.visible = self.open_on_join left_flow['gui-left-hide'].style.visible = true end + end + if is_type(self.draw,'function') then self:draw(frame) else frame.style.visible = false error('No Callback On '..self.name) end + return frame +end + +--- Toggles the visibility of the gui based on some conditions +-- @usage left:toggle(player) -- returns new state +-- @tparam LuaPlayer player the player to toggle the gui for, remember there are condition which need to be met +-- @treturn boolean the new state that the gui is in +function left._prototype:toggle(player) + player = Game.get_player(player) + local left_flow = mod_gui.get_frame_flow(player) + if not left_flow[self.name] then self:first_open(player) end + local left_frame = left_flow[self.name] + local open = false + if is_type(self.can_open,'function') then + local success, err = pcall(self.can_open,player) + if not success then error(err) + elseif err == true then open = true + elseif global.over_ride_left_can_open then + if is_type(Role,'table') then + if Role.allowed(player,self.name) then open = true + else open = {'ExpGamingCore_Gui.unauthorized'} end + else open = true end + else open = err end + else + if is_type(Role,'table') then + if Role.allowed(player,self.name) then open = true + else open = {'ExpGamingCore_Gui.unauthorized'} end + else open = true end + end + if open == true and left_frame.style.visible ~= true then + left_frame.style.visible = true + left_flow['gui-left-hide'].style.visible = true + else + left_frame.style.visible = false + local count = 0 + for _,child in pairs(left_flow.children) do if child.style.visible then count = count+1 end if count > 1 then break end end + if count == 1 and left_flow['gui-left-hide'] then left_flow['gui-left-hide'].style.visible = false end + end + if open == false then player_return({'ExpGamingCore_Gui.cant-open-no-reason'},defines.textcolor.crit,player) player.play_sound{path='utility/cannot_build'} + elseif open ~= true then player_return({'ExpGamingCore_Gui.cant-open',open},defines.textcolor.crit,player) player.play_sound{path='utility/cannot_build'} end + return left_frame.style.visible +end + +script.on_event(defines.events.on_player_joined_game,function(event) + -- draws the left guis when a player first joins, fake_event is just because i am lazy + local player = Game.get_player(event) + local frames = Gui.data.left or {} + local left_flow = mod_gui.get_frame_flow(player) + if not left_flow['gui-left-hide'] then left.hide(left_flow).style.maximal_width=15 end + local done = {} + for _,name in pairs(order_config) do + local left_frame = Gui.data.left[name] + if left_frame then + done[name] = true + left_frame:first_open(player) + end + end + for name,left_frame in pairs(frames) do + if not done[name] then left_frame:first_open(player) end + end +end) + +script.on_event(defines.events.on_tick,function(event) + if ((event.tick+10)/(3600*game.speed)) % 15 == 0 then + left.update() + end +end) + +function left.on_init() + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end +end + +-- calling will attempt to add a new gui +return setmetatable(left,{__call=function(self,...) return self.add(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/left/order_config.lua b/modules/ExpGamingCore/Gui/left/order_config.lua new file mode 100644 index 00000000..7f19658f --- /dev/null +++ b/modules/ExpGamingCore/Gui/left/order_config.lua @@ -0,0 +1,13 @@ +return { + 'server-info', + 'readme', + 'science', + 'rockets', + 'player-list', + 'tasklist', + 'warp-list', + 'polls', + 'announcements', + 'admin-commands', + 'game-settings' +} \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/left/softmod.json b/modules/ExpGamingCore/Gui/left/softmod.json new file mode 100644 index 00000000..d02b320e --- /dev/null +++ b/modules/ExpGamingCore/Gui/left/softmod.json @@ -0,0 +1,26 @@ +{ + "name": "ExpGamingCore.Gui.left", + "version": "4.0.0", + "description": "Adds an easy way to create auto updating left guis with toggle buttons.", + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Left", + "AutoUpdate" + ], + "collection": "ExpGamingCore.Gui@4.0.0", + "dependencies": { + "mod-gui": "*", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Server": "^4.0.0", + "FactorioStdLib.Color": "^0.8.0", + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingCore.Gui.inputs": "^4.0.0", + "ExpGamingCore.Gui.toolbar": "?^4.0.0", + "ExpGamingCore.Role": "?^4.0.0" + }, + "submodules": {} +} diff --git a/modules/ExpGamingCore/Gui/locale/de.cfg b/modules/ExpGamingCore/Gui/locale/de.cfg new file mode 100644 index 00000000..fbdba2f7 --- /dev/null +++ b/modules/ExpGamingCore/Gui/locale/de.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 - Unbefugt: Du hast keinen Zugriff auf diese Befehle! +cant-open=Du kannst dieses Menü nicht öffnen, Grund: __1__ +cant-open-no-reason=Du kannst dieses Menü gerade nicht öffnen. \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/locale/en.cfg b/modules/ExpGamingCore/Gui/locale/en.cfg new file mode 100644 index 00000000..f7eb1a6a --- /dev/null +++ b/modules/ExpGamingCore/Gui/locale/en.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 - Unauthorized: Access is denied due to invalid credentials +cant-open=You can't open this panel right now, reason: __1__ +cant-open-no-reason=You can't open this panel right now \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/locale/fr.cfg b/modules/ExpGamingCore/Gui/locale/fr.cfg new file mode 100644 index 00000000..a8976a4e --- /dev/null +++ b/modules/ExpGamingCore/Gui/locale/fr.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 - Unauthorized: Access is denied due to invalid credentials +cant-open=You can not open this panel right now, reason: __1__ +cant-open-no-reason=You can not open this panel right now \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/locale/nl.cfg b/modules/ExpGamingCore/Gui/locale/nl.cfg new file mode 100644 index 00000000..d53dc64c --- /dev/null +++ b/modules/ExpGamingCore/Gui/locale/nl.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 - Onbevoegd: toegang wordt geweigerd vanwege ongeldige inloggegevens +cant-open=Je kan dit momenteel niet openen. Reden: __1__ +cant-open-no-reason=Je kan dit momenteel niet openen. \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/locale/sv-SE.cfg b/modules/ExpGamingCore/Gui/locale/sv-SE.cfg new file mode 100644 index 00000000..279ba842 --- /dev/null +++ b/modules/ExpGamingCore/Gui/locale/sv-SE.cfg @@ -0,0 +1,4 @@ +[ExpGamingCore_Gui] +unauthorized=401 -Otillåten: Tillgång nekas på grund av otillräcklig säkerhetsprövning. +cant-open=Du kan inte öppna den här panelen just nu, orsak: __1__ +cant-open-no-reason=Du kan inte öppna den här panelen just nu \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/popup/control.lua b/modules/ExpGamingCore/Gui/popup/control.lua new file mode 100644 index 00000000..7a49bae3 --- /dev/null +++ b/modules/ExpGamingCore/Gui/popup/control.lua @@ -0,0 +1,130 @@ +--- Adds a location for popups which can be dismissed by a player and created from other scripts +-- @module ExpGamingCore.Gui.Popup +-- @alias popup +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +--- This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module +-- @function _comment + +local Game = require('FactorioStdLib.Game') +local mod_gui = require('mod-gui') +local Gui = require('ExpGamingCore.Gui') +local Server -- loaded on_init + +local popup = {} +popup._prototype = {} + +--- Used to add a popup gui style +-- @usage Gui.left.add{name='foo',caption='Foo',draw=function} +-- @usage return_value(data,player) -- opens popup for one player use popup.open to open for more than one player +-- @param obj this is what will be made, needs a name and a draw function(root_frame,data) +-- @return the object that is made, calling the returned value will open the popup for that player +function popup.add(obj) + if not is_type(obj,'table') then return end + if not is_type(obj.name,'string') then return end + verbose('Created Popup Gui: '..obj.name) + setmetatable(obj,{__index=popup._prototype,__call=function(self,data,player) local players = player and {player} or nil return popup.open(self.name,data,players) end}) + local name = obj.name; obj.name = nil + Gui.data('popup',name,obj) + obj.name = name + return obj +end + +-- this is used by the script to find the popup flow +function popup.flow(player) + player = Game.get_player(player) + if not player then error('Invalid Player',2) end + local flow = mod_gui.get_frame_flow(player).popups + if not flow then flow = mod_gui.get_frame_flow(player).add{name='popups',type='flow',direction='vertical'} flow.style.visible=false end + return flow +end + +--- Use to open a popup for these players +-- @usage Gui.popup.open('ban',nil,{player=1,reason='foo'}) +-- @tparam string style this is the name you gave to the popup when added +-- @param data this is the data that is sent to the draw function +-- @tparam[opt=game.connected_players] table players the players to open the popup for +function popup.open(style,data,players) + local _popup = Gui.data.popup[style] + players = players or game.connected_players + data = data or {} + if not _popup then return end + if not Server or not Server._thread then + for _,player in pairs(players) do + if _popup.left then _popup.left:close(player) end + local flow = popup.flow(player) + flow.style.visible=true + local _frame = flow.add{ + type='frame', + direction='horizontal', + style=mod_gui.frame_style + } + local frame = _frame.add{ + type='frame', + name='inner_frame', + direction='vertical', + style='image_frame' + } + _popup.close(_frame) + if is_type(_popup.draw,'function') then + local success, err = pcall(_popup.draw,_popup,frame,data) + if not success then error(err) end + else error('No Draw On Popup '.._popup.name) end + end + else + Server.new_thread{ + data={players=players,popup=_popup,data=data} + }:on_event('tick',function(self) + if #self.data.players == 0 then self:close() return end + local player = table.remove(self.data.players,1) + if self.data.popup.left then self.data.popup.left:close(player) end + local flow = popup.flow(player) + flow.style.visible=true + local _frame = flow.add{ + type='frame', + direction='horizontal', + style=mod_gui.frame_style + } + local frame = _frame.add{ + type='frame', + name='inner_frame', + direction='vertical', + style='image_frame' + } + self.data.popup.close(_frame) + if is_type(self.data.popup.draw,'function') then + local success, err = pcall(self.data.popup.draw,self.data.popup,frame,self.data.data) + if not success then error(err) end + else error('No Draw On Popup '..self.data.popup.name) end + end):open() + end +end + +function popup._prototype:add_left(obj) + if not Gui.left then return end + obj.name = obj.name or self.name + self.left = Gui.left(obj) +end + +function popup.on_init() + if loaded_modules['ExpGamingCore.Server'] then Server = require('ExpGamingCore.Server') end +end + +function popup.on_post() + popup._prototype.close = Gui.inputs.add{ + type='button', + name='popup-close', + caption='utility/set_bar_slot', + tooltip='Close This Popup' + }:on_event('click',function(event) + local frame = event.element.parent + local parent = frame.parent + if frame and frame.valid then frame.destroy() if #parent.children == 0 then parent.style.visible = false end end + end) +end + +script.on_event(defines.events.on_player_joined_game,popup.flow) + +-- calling will attempt to add a new popup style +return setmetatable(popup,{__call=function(self,...) return self.add(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/popup/softmod.json b/modules/ExpGamingCore/Gui/popup/softmod.json new file mode 100644 index 00000000..f4b3f736 --- /dev/null +++ b/modules/ExpGamingCore/Gui/popup/softmod.json @@ -0,0 +1,24 @@ +{ + "name": "ExpGamingCore.Gui.popup", + "version": "4.0.0", + "description": "Adds popup guis to the gui system which builds upon the left gui system.", + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Popup", + "Left" + ], + "collection": "ExpGamingCore.Gui@4.0.0", + "dependencies": { + "mod-gui": "*", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingCore.Gui.inputs": "^4.0.0", + "ExpGamingCore.Server": "?^4.0.0", + "ExpGamingCore.Gui.left": "?^4.0.0" + }, + "submodules": {} +} diff --git a/modules/ExpGamingCore/Gui/softmod.json b/modules/ExpGamingCore/Gui/softmod.json new file mode 100644 index 00000000..7363526b --- /dev/null +++ b/modules/ExpGamingCore/Gui/softmod.json @@ -0,0 +1,29 @@ +{ + "name": "ExpGamingCore.Gui", + "version": "4.0.0", + "description": "Adds a objective version to custom guis.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Library", + "Lib", + "ExpGaming", + "Core", + "Gui", + "ExpGui" + ], + "dependencies": { + "ExpGamingLib": "^4.0.0", + "FactorioStdLib.Table": "^0.8.0", + "FactorioStdLib.Color": "^0.8.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Server": "?^4.0.0" + }, + "collection": "ExpGamingCore@4.0.0", + "submodules": { + "ExpGamingCore.Gui.center": "4.0.0", + "ExpGamingCore.Gui.inputs": "4.0.0", + "ExpGamingCore.Gui.left": "4.0.0", + "ExpGamingCore.Gui.popup": "4.0.0", + "ExpGamingCore.Gui.toolbar": "4.0.0" + } +} diff --git a/modules/ExpGamingCore/Gui/src/server.lua b/modules/ExpGamingCore/Gui/src/server.lua new file mode 100644 index 00000000..1b613e11 --- /dev/null +++ b/modules/ExpGamingCore/Gui/src/server.lua @@ -0,0 +1,40 @@ +--- This file will be loaded when ExpGamingCore.Server is present +-- @function _comment + +local Game = require('FactorioStdLib.Game') +local Server = require('ExpGamingCore.Server') + +Server.add_module_to_interface('ExpGui','ExpGamingCore.Gui') + +--- Adds a server thread that allows the camera follows to be toggled off and on +return function() + Server.new_thread{ + name='camera-follow', + data={cams={},cam_index=1,players={}} + }:on_event('tick',function(self) + local update = 4 + if self.data.cam_index >= #self.data.cams then self.data.cam_index = 1 end + if update > #self.data.cams then update = #self.data.cams end + for cam_offset = 0,update do + local _cam = self.data.cams[self.data.cam_index+cam_offset] + if not _cam then break end + if not _cam.cam.valid then table.remove(self.data.cams,self.data.cam_index) + elseif not _cam.entity.valid then table.remove(self.data.cams,self.data.cam_index) + else _cam.cam.position = _cam.entity.position if not _cam.surface then _cam.cam.surface_index = _cam.entity.surface.index end + end + end + self.data.cam_index = self.data.cam_index+update + end):on_event(defines.events.on_player_respawned,function(self,event) + if self.data.players[event.player_index] then + local remove = {} + local player = Game.get_player(event) + for index,cam in pairs(self.data.players[event.player_index]) do + if cam.valid then table.insert(self.data.cams,{cam=cam,entity=player.character,surface=player.surface}) + else table.insert(remove,index) end + end + for n,index in pairs(remove) do + table.remove(self.data.players[event.player_index],index-n+1) + end + end + end):open() +end \ No newline at end of file diff --git a/ExpCore/GuiParts/test.lua b/modules/ExpGamingCore/Gui/src/test.lua similarity index 74% rename from ExpCore/GuiParts/test.lua rename to modules/ExpGamingCore/Gui/src/test.lua index 849e4b98..9ba60632 100644 --- a/ExpCore/GuiParts/test.lua +++ b/modules/ExpGamingCore/Gui/src/test.lua @@ -1,18 +1,28 @@ --- this is just testing all the diffrent inputs to open test use /c Gui.test() +--- Used to test all gui elements and parts can be used in game via Gui.test() +-- @module ExpGamingCore.Gui.Test +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE -local gui_tset_close = Gui.inputs.add{ +--- This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module +-- @function _comment + +local Game = require('FactorioStdLib.Game') +local Gui = Gui -- this is to force gui to remain in the ENV +local mod_gui = require("mod-gui") + +local gui_test_close = Gui.inputs{ name='gui-test-close', type='button', caption='Close Test Gui' }:on_event('click',function(event) event.element.parent.destroy() end) -local caption_test = Gui.inputs.add{ +local caption_test = Gui.inputs{ name='text-button', type='button', caption='Test' }:on_event('click',function(event) game.print('test') end) -local sprite_test = Gui.inputs.add{ +local sprite_test = Gui.inputs{ name='sprite-button', type='button', sprite='item/lab' @@ -43,30 +53,30 @@ local input_test = Gui.inputs.add_button('test-inputs','Try RMB','alt,ctrl,shift 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) +}):on_event('error',function(err) game.print('this is error handling') end) local elem_test = Gui.inputs.add_elem_button('test-elem','item','Testing Elems',function(player,element,elem) player_return(elem.type..' '..elem.value,nil,player) end) -local check_test = Gui.inputs.add_checkbox('test-check',false,'Cheat Mode',function(player,parent) - return game.players[parent.player_index].cheat_mode -end,function(player,element) - player.cheat_mode = true +local check_test = Gui.inputs.add_checkbox('test-check',false,'Cheat Mode',function(player,parent) + return game.players[parent.player_index].cheat_mode +end,function(player,element) + player.cheat_mode = true end,function(player,element) player.cheat_mode = false end) -local radio_test = Gui.inputs.add_checkbox('test-radio',true,'Kill Self',function(player,parent) +local radio_test = Gui.inputs.add_checkbox('test-radio',true,'Kill Self',function(player,parent) return false -end,function(player,element) +end,function(player,element) if player.character then player.character.die() end Gui.inputs.reset_radio(element.parent['test-radio-reset']) end) -local radio_test_reset = Gui.inputs.add_checkbox('test-radio-reset',true,'Reset Kill Self',function(player,parent) +local radio_test_reset = Gui.inputs.add_checkbox('test-radio-reset',true,'Reset Kill Self',function(player,parent) return not parent['test-radio'].state -end,function(player,element) +end,function(player,element) Gui.inputs.reset_radio(element.parent['test-radio']) end) @@ -90,29 +100,33 @@ local drop_test = Gui.inputs.add_drop_down('test-drop',table.keys(defines.color) player.chat_color = defines.color[selected] end) -local function test_gui(event) - if not game.player and not event.player_index then return end - local player = game.player or Game.get_player(event) +--- The funcation that is called when calling Gui.test +-- @function Gui.test +-- @usage Gui.test() -- draws test gui +-- @param[opt=game.player] player a pointer to a player to draw the test gui for +local function test_gui(player) + local player = game.player or Game.get_player(player) or nil + if not player then return end if mod_gui.get_frame_flow(player)['gui-test'] then mod_gui.get_frame_flow(player)['gui-test'].destroy() end local frame = mod_gui.get_frame_flow(player).add{type='frame',name='gui-test',direction='vertical'} - gui_tset_close:draw(frame) - caption_test:draw(frame) - sprite_test:draw(frame) - input_test:draw(frame) - elem_test:draw(frame) - check_test:draw(frame) - radio_test:draw(frame) - radio_test_reset:draw(frame) - text_test:draw(frame) - box_test:draw(frame) - slider_test:draw(frame) - drop_test:draw(frame) + gui_test_close(frame) + caption_test(frame) + sprite_test(frame) + input_test(frame) + elem_test(frame) + check_test(frame) + radio_test(frame) + radio_test_reset(frame) + text_test(frame) + box_test(frame) + slider_test(frame) + drop_test(frame) end Gui.toolbar.add('open-gui-test','Open Test Gui','Opens the test gui with every input',test_gui) -- testing the center gui -Gui.center.add{ +Gui.center{ name='test-center', caption='Gui Center', tooltip='Just a gui test' @@ -125,11 +139,11 @@ end):add_tab('tab-2','Tab 2','Just a tab',function(frame) end) -- testing the left gui -Gui.left.add{ +Gui.left{ name='test-left', caption='Gui Left', tooltip='just testing', - draw=function(frame) + draw=function(self,frame) for _,player in pairs(game.connected_players) do frame.add{type='label',caption=player.name} end @@ -140,26 +154,26 @@ Gui.left.add{ local text_popup = Gui.inputs.add_text('test-popup-text',true,'Message To Send',function(player,text,element) element.text = text end) -local send_popup = Gui.inputs.add{ +local send_popup = Gui.inputs{ type='button', name='test-popup-send', caption='Send Message' }:on_event('click',function(event) local player = Game.get_player(event) local message = event.element.parent['test-popup-text'].text - Gui.popup.open('test-popup',{player=player.name,message=message}) + Gui.popup.open('test-popup',{message=message,player=player.name}) end) -Gui.popup.add{ +Gui.popup{ name='test-popup', caption='Gui Popup', - draw=function(frame,data) + draw=function(self,frame,data) frame.add{type='label',caption='Opened by: '..data.player} frame.add{type='label',caption='Message: '..data.message} end }:add_left{ caption='Gui Left w/ Popup', tooltip='Send a message', - draw=function(frame) + draw=function(self,frame) text_popup:draw(frame) send_popup:draw(frame) end diff --git a/modules/ExpGamingCore/Gui/toolbar/control.lua b/modules/ExpGamingCore/Gui/toolbar/control.lua new file mode 100644 index 00000000..cae2f467 --- /dev/null +++ b/modules/ExpGamingCore/Gui/toolbar/control.lua @@ -0,0 +1,90 @@ +--- Adds a toolbar to the top left of the screen +-- @module ExpGamingCore.Gui.Toolbar +-- @alias toolbar +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +--- This is a submodule of ExpGamingCore.Gui but for ldoc reasons it is under its own module +-- @function _comment + +local Game = require('FactorioStdLib.Game') +local mod_gui = require('mod-gui') +local Gui = require('ExpGamingCore.Gui') +local order_config = require(module_path..'/order_config') +local Role -- this is optional and is handled by it being present, it is loaded on init + +local toolbar = {} + +toolbar.hide = Gui.inputs{ + name='gui-toolbar-hide', + type='button', + caption='<' +}:on_event('click',function(event) + if event.element.caption == '<' then + event.element.caption = '>' + for _,child in pairs(event.element.parent.children) do + if child.name ~= event.element.name then child.style.visible = false end + end + else + event.element.caption = '<' + for _,child in pairs(event.element.parent.children) do + if child.name ~= event.element.name then child.style.visible = true end + end + end +end) + +--- 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 +-- @tparam 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, calling the returned value will draw the toolbar button added +function toolbar.add(name,caption,tooltip,callback) + verbose('Created Toolbar Button: '..name) + local button = Gui.inputs.add{type='button',name=name,caption=caption,tooltip=tooltip} + button:on_event(Gui.inputs.events.click,callback) + Gui.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) + player = Game.get_player(player) + if not player then return end + local toolbar_frame = mod_gui.get_button_flow(player) + toolbar_frame.clear() + if not Gui.data.toolbar then return end + toolbar.hide(toolbar_frame).style.maximal_width = 15 + local done = {} + for _,name in pairs(order_config) do + local button = Gui.data.toolbar[name] + if button then + done[name] = true + if is_type(Role,'table') then + if Role.allowed(player,name) then + button(toolbar_frame) + end + else button(toolbar_frame) end + end + end + for name,button in pairs(Gui.data.toolbar) do + if not done[name] then + if is_type(Role,'table') then + if Role.allowed(player,name) then + button(toolbar_frame) + end + else button(toolbar_frame) end + end + end +end + +function toolbar.on_init() + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end +end + +script.on_event({defines.events.on_role_change,defines.events.on_player_joined_game},toolbar.draw) +-- calling with only a player will draw the toolbar for that player, more params will attempt to add a button +return setmetatable(toolbar,{__call=function(self,player,extra,...) if extra then return self.add(player,extra,...) else self.draw(player) end end}) \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/toolbar/order_config.lua b/modules/ExpGamingCore/Gui/toolbar/order_config.lua new file mode 100644 index 00000000..7f19658f --- /dev/null +++ b/modules/ExpGamingCore/Gui/toolbar/order_config.lua @@ -0,0 +1,13 @@ +return { + 'server-info', + 'readme', + 'science', + 'rockets', + 'player-list', + 'tasklist', + 'warp-list', + 'polls', + 'announcements', + 'admin-commands', + 'game-settings' +} \ No newline at end of file diff --git a/modules/ExpGamingCore/Gui/toolbar/softmod.json b/modules/ExpGamingCore/Gui/toolbar/softmod.json new file mode 100644 index 00000000..54884fbf --- /dev/null +++ b/modules/ExpGamingCore/Gui/toolbar/softmod.json @@ -0,0 +1,23 @@ +{ + "name": "ExpGamingCore.Gui.toolbar", + "version": "4.0.0", + "description": "Adds a toolbar at the top of the screen", + "author": "Cooldude2606", + "contact": "Discord: Cooldude26060#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Toolbar", + "Buttons" + ], + "collection": "ExpGamingCore.Gui@4.0.0", + "dependencies": { + "mod-gui": "*", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingCore.Gui.inputs": "^4.0.0", + "ExpGamingCore.Role": "?^4.0.0" + }, + "submodules": {} +} diff --git a/modules/ExpGamingCore/Role/config.lua b/modules/ExpGamingCore/Role/config.lua new file mode 100644 index 00000000..d755336e --- /dev/null +++ b/modules/ExpGamingCore/Role/config.lua @@ -0,0 +1,278 @@ +Role.add_flag('is_default') -- this must be included in at least one role +Role.add_flag('is_root',function(player,state) + if state then game.print('--- !!!ALERT!!! --- '..player.name..' has been given a role with ROOT ACCESS --- !!!ALERT!!! ---') end + if player.character then player.character.destructible = not state end +end) -- the SERVER role will have root but you may assign this to other roles +-- the two above and used internally and should NOT have their names changed and should NOT be removed but the state function MAY be changed +Role.add_flag('is_antiroot',function(player,state) if player.character then player.character.destructible = not state end end) -- not required but setting true will disallow everything for that role +Role.add_flag('is_admin',function(player,state) player.admin = state end) -- highly recommenced but not required +Role.add_flag('is_spectator',function(player,state) player.spectator = state end) +Role.add_flag('is_jail',function(player,state) if player.character then player.character.active = not state end end) +Role.add_flag('allow_afk_kick') +Role.add_flag('is_donator') +Role.add_flag('is_timed') +Role.add_flag('is_verified') +Role.add_flag('not_reportable') + +-- Root +Role{ + name='Root', + short_hand='Root', + tag='[Root]', + group='Root', + colour={r=255,b=255,g=255}, + is_root=true, + is_admin=true, + is_spectator=true, + not_reportable=true, + allow={} +} +Role{ + name='Community Manager', + short_hand='Com Mngr', + tag='[Com Mngr]', + group='Root', + colour={r=150,g=68,b=161}, + is_admin=true, + is_spectator=true, + is_donator=true, + not_reportable=true, + allow={} +} +Role{ + name='Developer', + short_hand='Dev', + tag='[Dev]', + group='Root', + colour={r=179,g=125,b=46}, + is_admin=true, + is_spectator=true, + is_donator=true, + not_reportable=true, + allow={ + ['interface']=true, + ['cheat-mode']=true + } +} + +-- Admin +Role{ + name='Administrator', + short_hand='Admin', + tag='[Admin]', + group='Admin', + colour={r=233,g=63,b=233}, + is_admin=true, + is_spectator=true, + is_verified=true, + not_reportable=true, + allow={ + ['game-settings']=true, + ['always-warp']=true, + ['admin-items']=true + } +} +Role{ + name='Moderator', + short_hand='Mod', + tag='[Mod]', + group='Admin', + colour={r=0,g=170,b=0}, + is_admin=true, + is_spectator=true, + is_verified=true, + not_reportable=true, + allow={ + ['set-home']=true, + ['home']=true, + ['return']=true, + ['announcements']=true, + ['rank-changer']=true, + } +} +Role{ + name='Trainee', + short_hand='TrMod', + tag='[TrMod]', + group='Admin', + colour={r=0,g=196,b=137}, + is_spectator=true, + is_verified=true, + not_reportable=true, + allow={ + ['go-to']=true, + ['bring']=true, + ['set-home']=false, + ['home']=false, + ['return']=false, + ['bonus']=false, + ['admin-commands']=true, + ['warn']=true, + ['temp-ban']=true, + ['clear-warnings']=true, + ['clear-reports']=true, + ['clear-all']=true, + ['clear-inv']=true, + } +} + +-- High Member +Role{ + name='Sponsor', + short_hand='Spon', + tag='[Sponsor]', + group='HiMember', + colour={r=247,g=246,b=54}, + is_spectator=true, + is_donator=true, + allow={} +} +Role{ + name='Pay to Win', + short_hand='P2W', + tag='[P2W]', + group='HiMember', + colour={r=238,g=172,b=44}, + is_donator=true, + allow={ + ['jail']=true, + ['unjail']=true, + ['bonus']=true, + ['bonus-respawn']=true + } +} +Role{ + name='Donator', + short_hand='Don', + tag='[Donator]', + group='HiMember', + colour={r=230,g=99,b=34}, + is_donator=true, + allow_afk_kick=true, + allow={ + ['set-home']=true, + ['home']=true, + ['return']=true, + } +} +Role{ + name='Partner', + short_hand='Part', + tag='[Partner]', + group='HiMember', + colour={r=140,g=120,b=200}, + allow_afk_kick=true, + allow={ + ['global-chat']=true, + } +} +Role{ + name='Veteran', + short_hand='Vet', + tag='[Veteran]', + group='HiMember', + colour={r=140,g=120,b=200}, + is_timed=true, + is_verified=true, + allow_afk_kick=true, + time=600, -- 10 hours + allow={ + ['tree-decon']=true, + ['create-poll']=true, + ['repair']=true + } +} + +-- Member +Role{ + name='Member', + short_hand='Mem', + tag='[Member]', + group='Member', + colour={r=24,g=172,b=188}, + is_verified=true, + allow_afk_kick=true, + allow={ + ['edit-tasklist']=true, + ['make-warp']=true, + ['nuke']=true, + ['verified']=true + } +} +Role{ + name='Regular', + short_hand='Reg', + tag='[Regular]', + group='Member', + colour={r=79,g=155,b=163}, + allow_afk_kick=true, + is_timed=true, + time=180, -- 3 hours + allow={ + ['kill']=true, + ['decon']=true, + ['capsules']=true + } +} + +-- Guest +Role{ + name='Guest', + short_hand='', + tag='', + group='User', + colour={r=185,g=187,b=160}, + allow_afk_kick=true, + is_default=true, + allow={ + ['player-list']=true, + ['readme']=true, + ['rockets']=true, + ['science']=true, + ['tasklist']=true, + ['report']=true, + ['warp-list']=true, + ['polls']=true, + ['tag']=true, + ['tag-clear']=true, + ['report']=true + } +} + +-- Jail +Role{ + name='Jail', + short_hand='Jail', + tag='[Jail]', + group='Jail', + colour={r=50,g=50,b=50}, + is_jail=true, + is_antiroot=true, + allow={} +} + +Role.order = { + 'Root', + 'Community Manager', + 'Developer', + 'Administrator', + 'Moderator', + 'Trainee', + 'Sponsor', + 'Pay to Win', + 'Donator', + 'Partner', + 'Veteran', + 'Member', + 'Regular', + 'Guest', + 'Jail' +} + +Role.set_preassign{ + ["cooldude2606"]={"Developer","Admin","Mod"}, + ["aldldl"]={"Sponsor","Admin","Donator","Sponsor","Member","Mod"}, + ["arty714"]={"Admin","Community Manager","Member","Mod"}, + ["drahc_pro"]={"Admin","Member","Mod"}, + ["mark9064"]={"Admin","Member","Mod"} +} \ No newline at end of file diff --git a/modules/ExpGamingCore/Role/control.lua b/modules/ExpGamingCore/Role/control.lua new file mode 100644 index 00000000..364bc995 --- /dev/null +++ b/modules/ExpGamingCore/Role/control.lua @@ -0,0 +1,529 @@ +--- Adds roles where a player can have more than one role +-- @module ExpGamingCore.Role@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias Role + +-- Module Require +local Group = require('ExpGamingCore.Group') +local Game = require('FactorioStdLib.Game') + +-- Local Variables +local role_change_event_id = script.generate_event_name('on_role_change') +local RoleGlobal + +-- Module Define +local _RoleSelfReference +local module_verbose = false +local Role = { + _prototype={}, + order={}, + flags={}, + actions={}, + preassign={}, + meta={times={},groups={},count=0}, + roles=setmetatable({},{ + __index=table.autokey, + __newindex=function(tbl,key,value) + rawset(tbl,key,_RoleSelfReference.define(value)) + end + }), + on_init=function(self) + if loaded_modules['ExpGamingCore.Server'] then require('ExpGamingCore.Server').add_module_to_interface('Role','ExpGamingCore.Role') end + if loaded_modules['ExpGamingCore.Command'] then require(module_path..'/src/commands',{self=self}) end + if loaded_modules['ExpGamingCore.Sync'] then require(module_path..'/src/sync',{self=self,RoleGlobal=RoleGlobal}) end + end, + on_post=function(self) + -- creates a server role with root access + self.meta.server = self{name='SERVER',group='Root',is_root=true,allow={}} + -- loads the roles in config + require(module_path..'/config',{Role=self}) + self.order[0] = 'SERVER' + -- joins role allows into a chain + local previous + for index,role_name in pairs(self.order) do + local role = self.get(role_name) + if not role then error('Invalid role name in order listing: '..role_name) return end + if role.is_default then self.meta.default = role end + if role.is_timed then self.meta.times[role.name] = {index,role.time*3600} end + if not self.meta.groups[role.group.name] then self.meta.groups[role.group.name] = {lowest=index,highest=index} end + if self.meta.groups[role.group.name].highest > index then self.meta.groups[role.group.name].highest = index end + if self.meta.groups[role.group.name].lowest < index then self.meta.groups[role.group.name].lowest = index end + if previous then setmetatable(previous.allow,{__index=role.allow}) end + self.meta.count = self.meta.count+1 + role.index = index + previous = role + end + if previous then setmetatable(previous.allow,{__index=function(tbl,key) return false end}) + else error('Invalid roles, no roles to load.') end + end +} +_RoleSelfReference=Role + +-- Global Define +local global = global{ + change_cache_length=15, + changes={}, + latest_change={}, + preassign={}, + players={}, + roles={} +} +RoleGlobal = global +-- Function Define + +--- Used to set default roles for players who join +-- @usage Role.set_preassign{name={roles}} +function Role.set_preassign(tbl) if game then global.preassign = tbl else Role.preassign = tbl end end + +--- Defines a new instance of a role +-- @usage Role.define{name='Root',short_hand='Root',tag='[Root]',group='Root',colour={r=255,b=255,g=255},is_root=true,allow={}} -- returns new role +-- @usage Role{name='Root',short_hand='Root',tag='[Root]',group='Root',colour={r=255,b=255,g=255},is_root=true,allow={}} -- returns new role +-- @tparam table obj contains the strings: name,short_hand,tag a table called allow a table called colour and a pointer to a permission group +-- @treturn Role the role which has been made +function Role.define(obj) + if not type_error(game,nil,'Cant define Role during runtime.') then return end + if not type_error(obj.name,'string','Role creation is invalid: role.name is not a string') then return end + if not is_type(obj.short_hand,'string') then obj.short_hand = obj.name:sub(1,3) end + if not is_type(obj.tag,'string') then obj.tag = '['..obj.short_hand..']' end + if not is_type(obj.colour,'table') then obj.colour = {r=255,b=255,g=255} end + if not type_error(obj.allow,'table','Role creation is invalid: role.allow is not a table') then return end + obj.group = Group.get(obj.group) + if not type_error(obj.group,'table','Role creation is invalid: role.group is invalid') then return end + if obj.time and not type_error(obj.time,'number','Role creation is invalid: role.time is not a number') then return end + verbose('Created Role: '..obj.name) + setmetatable(obj,{__index=Role._prototype}) + obj.connected_players = setmetatable({self=obj,connected=true},Role._prototype.players_mt) + obj.players = setmetatable({self=obj},Role._prototype.players_mt) + rawset(Role.roles,obj.name,obj) + table.insert(Role.order,obj.name) + return obj +end + +--- Used to get the role of a player or the role by name +-- @usage Role.get('foo') -- returns group foo +-- @usage Role.get(player) -- returns group of player +-- @tparam ?LuaPlayer|pointerToPlayer|string mixed can either be the name of the role or a player identifier +-- @treturn table the group which was found or nil +function Role.get(mixed,forceIsRole) + local player = game and Game.get_player(mixed) + if player == SERVER then return {Role.meta.server} end + if not forceIsRole and player then + local rtn = {} + if not global.players[player.index] then return Role.meta.default and {Role.meta.default} or {} end + for _,role in pairs(global.players[player.index]) do table.insert(rtn,Role.get(role)) end + return rtn + elseif is_type(mixed,'table') and mixed.group then return mixed + elseif is_type(mixed,'string') then return Role.roles[mixed] + elseif is_type(mixed,'number') then + for _,role in pairs(Role.roles) do + if role.index == mixed then return role end + end + end +end + +--- Used to place a player into a role(s) +-- @usage Role.assign(player,'Root') +-- @usage Role.assign(player,{'Root','Foo'}) +-- @tparam ?LuaPlayer|pointerToPlayer player the player to assign the role to +-- @tparam ?string|role|table the role to add the player to, if its a table then it will act recursively though the table +-- @tparam[opt=''] ?LuaPlayer|pointerToPlayer by_player the player who assigned the roles to the player +-- @tparam[opt] table batch this is used internally to prevent multiple event calls, contains {role_index_in_batch,batch} +-- @treturn boolean was the player assigned the roles +function Role.assign(player,role,by_player,batch) + player = Game.get_player(player) + if not player then error('Invalid player #1 given to Role.assign.',2) return end + verbose('Assigning Roles: '..serpent.line(role)..' to: '..player.name) + -- this loops over a table of role if given; will return if ipairs returns, else will assume it was meant to be a role and error + if is_type(role,'table') and not role.name then + local ctn = 0 + for n,_role in ipairs(role) do ctn=ctn+1 Role.assign(player,_role,by_player,{n,role}) end + if ctn > 0 then if not batch then table.insert(global.changes[player.index],{'assign',role}) global.latest_change = {player.index,'assign',role} end return end + end + role = Role.get(role) + if not role then error('Invalid role #2 given to Role.assign.',2) return end + -- this acts as a way to prevent the global table getting too full + if not global.changes[player.index] then global.changes[player.index]={} end + if #global.changes[player.index] > global.change_cache_length then table.remove(global.changes[player.index],1) end + if not batch then table.insert(global.changes[player.index],{'assign',role.name}) global.latest_change = {player.index,'assign',role.name} end + return role:add_player(player,by_player,batch) +end + +--- Used to remove a player from a role(s) +-- @usage Role.unassign(player,'Root') +-- @tparam ?LuaPlayer|pointerToPlayer player the player to unassign the role to +-- @tparam ?string|role|table role the role to remove the player from, if its a table then it will act recursively though the table +-- @tparam[opt=''] ?LuaPlayer|pointerToPlayer by_player the player who unassigned the roles from the player +-- @tparam[opt] table batch this is used internally to prevent multiple event calls +-- @treturn boolean was the player unassigned the roles +function Role.unassign(player,role,by_player,batch) + player = Game.get_player(player) + if not player then error('Invalid player #1 given to Role.unassign.',2) return end + verbose('Assigning Roles: '..serpent.line(role)..' to: '..player.name) + -- this loops over a table of role if given; will return if ipairs returns, else will assume it was meant to be a role and error + if is_type(role,'table') and not role.name then + local ctn = 0 + for n,_role in ipairs(role) do ctn=ctn+1 Role.unassign(player,_role,by_player,{n,role}) end + if ctn > 0 then if not batch then table.insert(global.changes[player.index],{'unassign',role}) global.latest_change = {player.index,'unassign',role} end return end + end + role = Role.get(role) + if not role then error('Invalid role #2 given to Role.unassign.',2) return end + if not global.changes[player.index] then global.changes[player.index]={} end + -- this acts as a way to prevent the global table getting too full + if #global.changes[player.index] > global.change_cache_length then table.remove(global.changes[player.index],1) end + if not batch then table.insert(global.changes[player.index],{'unassign',role.name}) global.latest_change = {player.index,'unassign',role.name} end + return role:remove_player(player,by_player,batch) +end + +--- Returns the highest role given in a list, if a player is passed then it returns the highest role of the player +-- @usage Role.get_highest{'Root','Admin','Mod'} -- returns Root (given that root is highest) +-- @usage Role.get_highest(player) -- returns the players highest role +-- @tparam ?table|LuaPlayer|pointerToPlayer options table of options or a player +-- @treturn role the highest role given in the options +function Role.get_highest(options) + local player = Game.get_player(options) + if player then options = Role.get(player) end + if not type_error(options,'table','Invalid argument #1 to Role.get_highest, options is not a table of roles.') then return end + local highest_index = -1 + local highest + for _,role_name in pairs(options) do + local role = Role.get(role_name) + if not role then error('Invalid role inside options: '..serpent.line(role_name)) return end + if highest_index == -1 or role.index < highest_index then highest_index,highest = role.index,role end + end + return highest +end + +--- Uses the change cache to revert changes to players roles +-- @usage Role.revert(player) -- reverts the last change to the players roles +-- @tparam ?LuaPlayer|pointerToPlayer player the player to revert the changes of +-- @tparam[opt] ?LuaPlayer|pointerToPlayer the player who preformed the role revert +-- @tparam[opt=1] count the number of reverts to do, if 0 all changes cached are reverted +-- @treturn number the number of changes that occurred +function Role.revert(player,by_player,count) + player = Game.get_player(player) + if not player then error('Invalid player #1 given to Role.revert.',2) return end + if count and not type_error(count,'number','Invalid argument #2 to Role.revert, count is not a number.') then return end + local changes = global.changes[player.index] or {} + if #changes == 0 then error('Player has no role changes logged, can not revert.') end + count = count or 1 + local ctn = 0 + if count > #changes or count == 0 then count = #changes end + for i = 1,count do + local change = table.remove(changes) + if not change then break end + local batch = is_type(change[2],'table') and change[2] or {change[2]} + if change[1] == 'assign' then Role.unassign(player,change[2],by_player,batch) end + if change[1] == 'unassign' then Role.assign(player,change[2],by_player,batch) end + ctn=ctn+1 + end + return ctn +end + +--- Adds a flag which can be set on roles; these flags act as a quick way to access general role changes +-- @usage Role.add_flag('is_admin',function(player,state) player.admin = state end) -- the function is passed player and if the flag is true or false +-- @tparam string flag the name of the flag that is being added +-- @tparam[opt] function callback the function(player,state) which is called when a player loses or gains a flag, if nil no function is called +function Role.add_flag(flag,callback) + if not type_error(flag,'string','Invalid argument #1 to Role.add_flag, flag is not a string.') then return end + if callback and not type_error(callback,'function','Invalid argument #2 to Role.add_flag, callback is not a function.') then return end + verbose('Added flag: '..flag) + Role.flags[flag] = callback or true +end + +--- Checks if a player or role has the requested flag, if player all roles of player are checked (true has priority) +-- @usage Role.has_flag(role,'is_admin') -- returns true if this role has is_admin set +-- @tparam role|LuaPlayer|pointerToPlayer mixed the player or role that will be tested +-- @tparam string flag the flag to test for +-- @treturn boolean if the flag was true or false, false if nil +function Role.has_flag(mixed,flag) + if not type_error(flag,'string','Invalid argument #2 to Role.has_flag, flag is not a string.') then return end + local roles = Role.get(mixed) + if not type_error(roles,'table','Invalid argument #1 to Role.has_flag, mixed is not a role or player.') then return end + if #roles > 0 then for _,role in pairs(roles) do + if role:has_flag(flag) then return true end + end elseif roles:has_flag(flag) then return true end + return false +end + +--- Adds a action to be used by the role system +-- @usage Role.add_action('foo') +-- @tparam string action the name of the action that will be added +function Role.add_action(action) + if not type_error(action,'string','Invalid argument #1 to Role.add_action, action is not a string.') then return end + verbose('Added action: '..action) + table.insert(Role.actions,action) +end + +--- Checks if a player or role is allowed the requested action, if player all roles of player are checked (true has priority) +-- @usage Role.allowed(role,'foo') -- returns true if this role is allowed 'foo' +-- @tparam ?role|LuaPlayer|pointerToPlayer mixed the player or role that will be tested +-- @tparam string action the action to test for +-- @treturn boolean if the action is allowed for the player or role +function Role.allowed(mixed,action) + if not type_error(action,'string','Invalid argument #2 to Role.allowed, action is not a string.') then return end + local roles = Role.get(mixed) + if not type_error(roles,'table','Invalid argument #1 to Role.allowed, mixed is not a role or player.') then return end + if #roles > 0 then for _,role in pairs(roles) do + if role:allowed(action) then return true end + end elseif roles:allowed(action) then return true end + return false +end + +--- Prints to all roles and players of those roles which are greater than the given role (or if inv then all below) +-- @usage Role.print('Admin','Hello, World!') -- returns the number of players who received the message +-- @tparam ?role|string role the role which acts as the turning point of the print (always included regardless of inv value) +-- @param rtn the value that will be returned to the players +-- @tparam[opt] table colour the colour that you want the message printed in +-- @tparam[opt=false] boolean inv true to print to roles below, false to print to roles above +-- @treturn number the number of players who received the message +function Role.print(role,rtn,colour,inv) + role = Role.get(role,true) + if not type_error(role,'table','Invalid argument #1 to Role.print, role is invalid.') then return end + if colour and not type_error(colour,'table','Invalid argument #3 to Role.print, colour is not a table.') then return end + if inv and not type_error(inv,'boolean','Invalid argument #4 to Role.print, inv is not a boolean.') then return end + local message = inv and {'ExpGamingCore-Role.default-print',rtn} or {'ExpGamingCore-Role.print',role.name,rtn} + local change = inv and 1 or -1 + local ctn = 0 + local i = role.index + while true do + local _role = Role.get(i,true) + if not _role then break end + ctn=ctn+_role:print(message,colour) + i=i+change + end + return ctn +end + +--- Prints all registered roles and there important information (debug) +-- @tparam[opt] ?role|string the role to print the info of, if nil then all roles are printed in order of power +-- @tparam[opt=game.player] ?LuaPlayer|pointerToPlayer the player to print the info to, default the player who ran command +function Role.debug_output(role,player) + player = Game.get_player(player) or game.player + if not player then error('Invalid player #2 given to Role.debug_output.',2) return end + local function _output(_role) + local flags = {};for flag in pairs(Role.flags) do if _role:has_flag(flag) then table.insert(flags,flag) end end + local rtn = string.format('%s) %q-%q || Tag: %s Short Hand: %q Time: %s Flags: %s', + _role.index,_role.group.name,_role.name,_role.tag,_role.short_hand,tostring(_role.time),table.concat(flags,', ')) + player_return(rtn,_role.colour,player) + end + if role then + role = Role.get(role) + if not type_error(role,'table','Invalid argument #1 to Role.print, role is invalid.') then return end + _output(role) + else for index,_role in pairs(Role.roles) do _output(_role) end end +end + +--- Used to test if a role has a flag set +-- @usage role:has_flag('is_admin') -- returns true if the role has the flag 'is_admin' +-- @tparam string flag the flag to test for +-- @treturn boolean true if the flag is set else false +function Role._prototype:has_flag(flag) + if not self_test(self,'role','has_flag') then return end + if not type_error(flag,'string','Invalid argument #1 to role:has_flag, flag is not a string.') then return end + return self[flag] or false +end + +--- Used to test if a role is allowed an action +-- @usage role:allowed('foo') -- returns true if the role is allowed 'foo' +-- @tparam string action the action to test for +-- @treturn boolean true if the action is allowed else false +function Role._prototype:allowed(action) + if not self_test(self,'role','allowed') then return end + if not type_error(action,'string','Invalid argument #1 to role:allowed, action is not a string.') then return end + if self.is_antiroot then return false end + return self.allow[action] or self.is_root or false -- still include is_root exception flag +end + +--- Returns the players who have this role +-- @usage role:get_player() -- returns table of players +-- @usage role.players -- returns table of players +-- @usage role.connected_players -- returns table of online players +-- @tparam[opt] boolean online if true only returns online players +function Role._prototype:get_players(online) + if not self_test(self,'role','get_players') then return end + if online and not type_error(online,'boolean','Invalid argument #1 to role:get_players, online is not a boolean.') then return end + if not global.roles[self.name] then global.roles[self.name] = {} end + if self.is_default then if online then return game.connected_players else return game.players end end + local rtn = {} + for _,player_index in pairs(global.roles[self.name]) do + local player = game.players[player_index] + if player and not online or player.connected then table.insert(rtn,player) end + end + return rtn +end + +-- this is used to create a connected_players table +Role._prototype.players_mt = { + __call=function(tbl) return tbl.self:get_players(tbl.connected) end, + __pairs=function(tbl) + local players = tbl.self:get_players(tbl.connected) + local function next_pair(tbl,key) + local k, v = next(players, key) + if v then return k,v end + end + return next_pair, players, nil + end, + __ipairs=function(tbl) + local players = tbl.self:get_players(tbl.connected) + local function next_pair(tbl,key) + local k, v = next(players, key) + if v then return k,v end + end + return next_pair, players, nil + end +} + + +--- Prints a message to all players who have this role +-- @usage role:print('Hello, World!') -- returns number of players who received the message +-- @param rtn the message to print to the players +-- @tparam[opt] table colour the colour to print the message in +-- @treturn number the number of players who received the message +function Role._prototype:print(rtn,colour) + if not self_test(self,'role','print') then return end + if colour and not type_error(colour,'table','Invalid argument #2 to Role.print, colour is not a table.') then return end + local ctn = 0 + for _,player in pairs(self:get_players(true)) do ctn=ctn+1 player_return(rtn,colour,player) end + return ctn +end + +--- Returns a table that describes all the permissions and which this role is allowed +-- @usage role:get_permissions() -- returns table of permissions +-- @treturn table a table of permissions, only includes ones which were defined with Role.add_action +function Role._prototype:get_permissions() + if not self_test(self,'role','get_permissions') then return end + local rtn = {} + for _,action in pairs(Role.actions) do rtn[action] = self:allowed(action) end + return rtn +end + +--- Adds a player to this role (players can have more than one role) +-- @usage role:add_player(player) +-- @tparam ?LuaPlayer|PointerToPlayer player the player to add +-- @tparam[opt] ?LuaPlayer|PointerToPlayer by_player the player who ran the command +-- @tparam[opt] table batch this is used internally to prevent multiple event calls +function Role._prototype:add_player(player,by_player,batch) + if not self_test(self,'role','add_player') then return end + player = Game.get_player(player) + if not player then error('Invalid player #1 given to role:add_player.',2) return end + by_player = Game.get_player(by_player) or SERVER + if not global.roles[self.name] then global.roles[self.name] = {} end + if not global.players[player.index] then global.players[player.index] = {} end + local highest = Role.get_highest(player) or Role.meta.default + for _,player_index in pairs(global.roles[self.name]) do if player_index == player.index then return end end + table.insert(global.roles[self.name],player.index) + table.insert(global.players[player.index],self.name) + script.raise_event(role_change_event_id,{ + name=role_change_event_id, + tick=game.tick, + player_index=player.index, + by_player_index=by_player.index, + old_highest=highest.name, + role_name=self.name, + batch=batch and batch[2] or {self.name}, + batch_index=batch and batch[1] or 1, + effect='assign' + }) +end + +--- Removes a player from this role (players can have more than one role) +-- @usage role:remove_player(player) +-- @tparam ?LuaPlayer|PointerToPlayer player the player to remove +-- @tparam[opt] ?LuaPlayer|PointerToPlayer by_player the player who ran the command +-- @tparam[opt] table batch this is used internally to prevent multiple event calls +function Role._prototype:remove_player(player,by_player,batch) + if not self_test(self,'role','add_player') then return end + player = Game.get_player(player) + if not player then error('Invalid player #1 given to role:remove_player.',2) return end + by_player = Game.get_player(by_player) or SERVER + if not global.roles[self.name] then global.roles[self.name] = {} end + if not global.players[player.index] then global.players[player.index] = {} end + local highest = Role.get_highest(player) or Role.meta.default + local index = 0 + for _index,player_index in pairs(global.roles[self.name]) do if player_index == player.index then index=_index break end end + table.remove(global.roles[self.name],index) + for _index,role_name in pairs(global.players[player.index]) do if role_name == self.name then index=_index break end end + table.remove(global.players[player.index],index) + script.raise_event(role_change_event_id,{ + name=role_change_event_id, + tick=game.tick, + player_index=player.index, + by_player_index=by_player.index, + old_highest=highest.name, + role_name=self.name, + batch=batch and batch[2] or {self.name}, + batch_index=batch and batch[1] or 1, + effect='unassign' + }) +end + +-- Event Handlers Define +script.on_event(role_change_event_id,function(event) + -- variable init + local player = Game.get_player(event) + local by_player = Game.get_player(event.by_player_index) or SERVER + local role = Role.get(event.role_name) + local highest = Role.get_highest(player) + if not highest then Role.meta.default:add_player(player) highest = Role.meta.default end + -- gets the flags the player currently has + for flag,callback in pairs(Role.flags) do if is_type(callback,'function') then callback(player,Role.has_flag(player,flag)) end end + -- assign new tag and group of highest role + Group.assign(player,highest.group) + local old_highest_tag = Role.get(event.old_highest).tag or '' + local start, _end = string.find(player.tag,old_highest_tag,1,true) + if start and old_highest_tag ~= highest.tag then player.tag = string.sub(player.tag,0,start-1)..highest.tag..string.sub(player.tag,_end+1) end + if not start then player.tag = highest.tag player_return({'ExpGamingCore-Role.tag-reset'},nil,player) end + if player.online_time > 60 then + -- send a message to other players + if event.batch_index == 1 then + local names = {} + for _,name in pairs(event.batch) do local next_role = Role.get(name) if next_role then table.insert(names,next_role.name) end end + if event.effect == 'assign' then + if not role.is_jail then player.play_sound{path='utility/achievement_unlocked'} end + game.print{'ExpGamingCore-Role.default-print',{'ExpGamingCore-Role.assign',player.name,table.concat(names,', '),by_player.name}} + else + player.play_sound{path='utility/game_lost'} + game.print{'ExpGamingCore-Role.default-print',{'ExpGamingCore-Role.unassign',player.name,table.concat(names,', '),by_player.name}} + end + end + -- log change to file + game.write_file('role-change.json', + table.json({ + tick=game.tick, + effect=event.effect, + role_name=role.name, + player_name=player.name, + by_player_name=by_player.name, + play_time=player.online_time, + highest_role_name=highest.name, + old_highest=event.highest, + batch_count=#event.batch, + batch_index=event.batch_index + })..'\n' + , true, 0) + end +end) + +script.on_event(defines.events.on_player_created,function(event) + local player = Game.get_player(event) + local highest = Role.get_highest(player) or Role.meta.default + Group.assign(player,highest.group) + player.tag=highest.tag + if global.preassign[player.name:lower()] then Role.assign(player,global.preassign[player.name:lower()]) end + if Role.preassign[player.name:lower()] then Role.assign(player,Role.preassign[player.name:lower()]) end +end) + +script.on_event(defines.events.on_tick,function(event) + if game.tick%(3600*5) ~= 0 then return end -- every 5 minutes + for role_name, time in pairs(Role.meta.times) do + for _,player in pairs(game.connected_players) do + local highest = Role.get_highest(player) + if highest.index > time[1] and (player.online_time) > time[2] then Role.assign(player,role_name) end + end + end +end) + +-- Module Return +-- calling will attempt to define a new role +return setmetatable(Role,{__call=function(tbl,...) return tbl.define(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingCore/Role/locale/en.cfg b/modules/ExpGamingCore/Role/locale/en.cfg new file mode 100644 index 00000000..4cb41594 --- /dev/null +++ b/modules/ExpGamingCore/Role/locale/en.cfg @@ -0,0 +1,6 @@ +[ExpGamingCore-Role] +default-print=[Everyone]: __1__ +print=[__1__]: __2__ +assign=__1__ was assigned to __2__ by __3__ +unassign=__1__ was unassigned from __2__ by __3__ +tag-reset=Your Tag was reset due to a role change \ No newline at end of file diff --git a/modules/ExpGamingCore/Role/softmod.json b/modules/ExpGamingCore/Role/softmod.json new file mode 100644 index 00000000..3af9da54 --- /dev/null +++ b/modules/ExpGamingCore/Role/softmod.json @@ -0,0 +1,24 @@ +{ + "name": "ExpGamingCore.Role", + "version": "4.0.0", + "description": "Adds roles where a player can have more than one role", + "location": "FSM_ARCHIVE", + "keywords": [ + "Role", + "Ranks", + "Permissions", + "Alowed", + "Admin" + ], + "dependencies": { + "ExpGamingLib": "^4.0.0", + "FactorioStdLib.Table": "^0.8.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Group": "^4.0.0", + "ExpGamingCore.Server": "?^4.0.0", + "ExpGamingCore.Command": "?^4.0.0", + "ExpGamingCore.Sync": "?^4.0.0" + }, + "collection": "ExpGamingCore@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCore/Role/src/commands.lua b/modules/ExpGamingCore/Role/src/commands.lua new file mode 100644 index 00000000..612a781a --- /dev/null +++ b/modules/ExpGamingCore/Role/src/commands.lua @@ -0,0 +1,28 @@ +local Role = self + +commands.add_validation('player-rank',function(value,event) + local player,err = commands.validate['player'](value) + if err then return commands.error(err) end + local rtn = Role.get_highest(player).index > Role.get_highest(event).index and player or player.index == event.player_index and player or nil + if not rtn then return commands.error{'ExpGamingCore_Command.error-player-rank'} end return rtn +end) + +commands.add_validation('player-rank-online',function(value,event) + local player,err = commands.validate['player-online'](value) + if err then return commands.error(err) end + local player,err = commands.validate['player-rank'](player) + if err then return commands.error(err) end + return player +end) + +commands.add_validation('player-rank-alive',function(value,event) + local player,err = commands.validate['player-alive'](value) + if err then return commands.error(err) end + local player,err = commands.validate['player-rank'](player,event) + if err then return commands.error(err) end + return player +end) + +commands.add_middleware(function(player,command_name,event) + return Role.allowed(player,command_name) +end) \ No newline at end of file diff --git a/modules/ExpGamingCore/Role/src/sync.lua b/modules/ExpGamingCore/Role/src/sync.lua new file mode 100644 index 00000000..36f0fdbe --- /dev/null +++ b/modules/ExpGamingCore/Role/src/sync.lua @@ -0,0 +1,82 @@ +local Role = self +local RoleGlobal = RoleGlobal +local Sync = require('ExpGamingCore.Sync') +local Game = require('FactorioStdLib.Game') +local Color = require('FactorioStdLib.Color') + +-- just to hard reset the role sync +function Sync.set_roles(...) + Role.set_preassign(...) +end + +-- used to assign the role if the player is online, or add to the the preassign +function Sync.assign_role(player_name,roles,by_player_name) + if not game then return end + local preassign = RoleGlobal.preassign + local player_roles = preassign[player_name] + if Game.get_player(player_name) then Role.assign(player_name,roles,by_player_name) + else + if not is_type(roles,'table') then roles = {roles} end + if not player_roles then preassign[player_name] = roles return end + for _,role_name in pairs(roles) do + if not table.includes(player_roles,role_name) then table.insert(player_roles,role_name) end + end + end +end + +-- used to unassign the role if the player is online, or removes the preassign +function Sync.unassign_role(player_name,roles,by_player_name) + if not game then return end + local preassign = RoleGlobal.preassign + local player_roles = preassign[player_name] + if Game.get_player(player_name) then Role.unassign(player_name,roles,by_player_name) + else + if not is_type(roles,'table') then roles = {roles} end + if not player_roles then preassign[player_name] = nil return end + for _,role_name in pairs(roles) do + local index = table.index(player_roles,role_name) + if index then table.remove(player_roles,index) end + end + end +end + +Sync.add_update('roles',function() + if not game then return {'Offline'} end + local _rtn = {} + for _,role in pairs(Role.roles) do + local players = role:get_players() + local _players = {} + for k,player in pairs(players) do _players[k] = player.name end + local online = role:get_players(true) + local _online = {} + for k,player in pairs(online) do _online[k] = player.name end + _rtn[role.name] = {players=_players,online=_online,n_players=#_players,n_online=#_online} + end + return _rtn +end) + +-- Adds a caption to the info gui that shows the rank given to the player +if Sync.add_to_gui then + Sync.add_to_gui(function(player) + local names = {} + for _,role in pairs(Role.get(player)) do table.insert(names,role.name) end + return 'You have been assigned the roles: '..table.concat(names,', ') + end) +end + +-- adds a discord emit for rank changing +script.on_event('on_role_change',function(event) + local role = Role.get(event.role_name) + local player = Game.get_player(event) + local by_player = Game.get_player(event.by_player_index) or SERVER + if role.is_jail and RoleGlobal.last_change[1] ~= player.index then + Sync.emit_embedded{ + title='Player Jail', + color=Color.to_hex(defines.textcolor.med), + description='There was a player jailed.', + ['Player:']='<>'..player.name, + ['By:']='<>'..by_player.name, + ['Reason:']='No Reason' + } + end +end) \ No newline at end of file diff --git a/modules/ExpGamingCore/Server/control.lua b/modules/ExpGamingCore/Server/control.lua new file mode 100644 index 00000000..82f0ec68 --- /dev/null +++ b/modules/ExpGamingCore/Server/control.lua @@ -0,0 +1,556 @@ +--- Adds a thread system and event listening and a admin bypass (recommend to disable /c and use optional /interface) +-- @module ExpGamingCore.Server +-- @alias Server +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') +local Color = require('FactorioStdLib.Color') + +local Server = {} +local module_verbose = false --true|false + +--- Global Table +-- @table global +-- @field all a list of every thread (indexed by uuid) +-- @field queue an index for threads which will be resolved (contains uuids) +-- @field tick an index for threads which will run every tick (contains uuids) +-- @field timeout an index for threads which will timeout (contains uuids) +-- @field events an index of threads based on event ids (contains uuids) +-- @field paused an index of paused threads (contains uuids) +-- @field named a name index for thread uuids +-- @field print_to contains players that event details will be printed to +-- @field uuid contains the random number generator for the uuid system +local pre_load_uuid = 0 +local global = global{ + all={_n=0}, + queue={}, + tick={}, + timeout={}, + events={}, + paused={}, + named={}, + print_to={}, + uuid=0 +} + +--- Used to generate a new uuid for the thread system +-- @usage local uuid = tostring(Server.uuid) -- calling tostring locks the value +-- @treturn string the new uuid +Server.uuid = add_metatable({},function() + -- when it is called as a function + local uuid + if game then + global.uuid=global.uuid+1 + uuid=global.uuid+pre_load_uuid + verbose('Game UUID Increased: '..global.uuid..' ('..uuid..')') + else + pre_load_uuid=pre_load_uuid+1 + uuid=pre_load_uuid + verbose('Load UUID Increased: '..pre_load_uuid..' ('..uuid..')') + end + return add_metatable({uuid},nil,function(tbl) return string.format("%x", tostring(tbl[1])) end) +end,function() + -- when it is treated as a string + return tostring(Server.uuid()) +end) + +--- Redirect to the thread index +-- @usage Server.threads -- return #global.all +-- @usage Server.threads -- return global.all +-- @treturn[1] number the number of threads +-- @treturn[2] table table of all threads +Server.threads = setmetatable({},{ + __metatable=false, + __call=function(tbl) return global.all._n end, + __len=function(tbl) return global.all._n end, + __index=function(tbl,key) return rawget(global.all,key) end, + __newindex=function(tbl,key,value) rawset(global.all,key,value) end, + __pairs=function(tbl) + local tbl = global.all + local function next_pair(tbl,key) + local k, v = next(tbl, key) + if type(v) ~= nil and k ~= '_n' then return k,v + else return next(tbl, k) end + end + return next_pair, tbl, nil + end +}) + +--- Generates a new thread object +-- @usage Server.new_thread{name='foo',data={}} +-- @tparam table obj the attributes to give to the thread +-- @treturn Server._thread the new thread created +function Server.new_thread(obj) return Server._thread:create(obj) end + +--- Used to get a thread via uuid or name (if one is assigned) +-- @usage Server.get_thread('decon') -- return thread +-- @param mixed either a uuid or the name given to a thread +-- @treturn[1] Server._thread the thread by that name or uuid +-- @treturn[2] boolean if false is returned then no thread exists +function Server.get_thread(mixed) + local threads = global + 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 Server._thread thread_to_queue the thread to be added to the queue, must be open and have a on_resolve function +-- @treturn boolean was it added successfully +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(global.queue,thread_to_queue.uuid) + return true +end + +--- Closes all active threads, can use force if it causes errors +-- @usage Server.close_all_threads() -- asks all threads to close +-- @usage Server.close_all_threads(true) -- forcefully close all threads +-- @tparam boolean with_force use force when closing +function Server.close_all_threads(with_force) + if not with_force then + for uuid,thread in pairs(Server.threads) do thread:close() end + else global.Server(true) end -- idk why you cant just use global even when global is defined at the top to be overridden +end + +--- Runs all the threads which have opened with an on_tick event +-- @usage Server.run_tick_threads() +function Server.run_tick_threads() + table.each(global.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 = Manager.sandbox(next_thread._tick,next_thread._env,next_thread) + if not success then next_thread:error(err) end + end + end) +end + +--- Checks the timeout on all active timeout threads +-- @usage Server.check_timeouts() +function Server.check_timeouts() + table.each(global.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 + +--- Used to print event info to a player +-- @usage Server._thread_debuger('Cooldude2606','on_player_died',true) -- will output event info to 'Cooldude2606' for 'on_player_died' +-- @tparam ?name|index|LuaPlayer player the player that the info will be returned to +-- @tparam ?name|index event the event that info will be returned fo +-- @tparam[opt=toggle] boolean state will info be returned, nil to toggle current state +function Server._thread_debuger(player,event,state) + player = Game.get_player(player) + event = tonumber(event) or Manager.event.names[event] + local print_to = global.print_to + print_to[player.index] = print_to[player.index] or {} + if state then print_to[player.index][event] = state + elseif print_to[player.index][event] then print_to[player.index][event] = false + else print_to[player.index][event] = true end +end + +--- Calls all threads on a certain game event (used with script.on_event) +-- @local Server._thread_handler +-- @usage script.on_event(defines.events,Server._thread_handler) -- adds this handler +-- @tparam table event the event that is called +function Server._thread_handler(event) + -- returns to players who have set _thread_debuger to true + table.each(global.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.textcolor.bg,player_index) + end + end,event) + -- gets the thread uuids + local event_id = event.name + local threads = global.events[event_id] + if not threads then return end + -- loops over the uuids + table.each(threads,function(uuid) + local thread = Server.get_thread(uuid) + if thread and thread:valid() then + if is_type(thread._events[event_id],'function') then + -- runs the function in the same env it was created (avoids desyncs) + local success, err = Manager.sandbox(thread._events[event_id],thread._env,thread,event) + -- if there is an error it asks the thread to deal with it + if not success then thread:error(err) end + end + end + end) +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 boolean if the handler was added +function Server.add_thread_handler(event) + if not is_type(event,'number') then return false end + local threads = global + if not threads.events[event] then + threads.events[event] = {} + script.on_event(event,Server._thread_handler) + return true + end + return false +end +]] + +--- Acts as a bypass for running functions, can accept a string +-- @usage Server.interface('local x = 1+1 print(x) return x') -- return 2 +-- @usage Server.interface('local x = 1+1 print(x)',true) -- will create a thread to run as root (this is the bypass) +-- @tparam ?string|function callback function to be ran +-- @tparam[opt] ?Server._thread|true use_thread run the command on a pre-made thread or let it make its own +-- @tparam[opt] table env run the env to run the command in must have _env key as true to be +-- @param[opt] ... any args you want to pass to the function +-- @treturn[1] boolean if no thread then it will return a true for the success +-- @return[1] if no thread then it will return the value(s) returned by the callback +-- @treturn[2] boolean if no thread then it will return a false for the success +-- @treturn[2] string if no thread then it will return a an err value +function Server.interface(callback,use_thread,env,...) + if use_thread then + -- if use_thread is true then it makes a new thread + if use_thread == true then use_thread = Server.new_thread{data={callback,env,...}} end + -- creates the resolve function for the thread + use_thread:on_event('resolve',function(thread) + local thread_callback = table.remove(thread.data,1) + thread_callback = is_type(thread_callback,'function') and thread_callback or loadstring(thread_callback) + local thread_env = table.remove(thread.data,1) + if is_type(thread_env,'table') and not is_type(thread_env.__self,'userdata') and thread_env._env == true then + local success, err = Manager.sandbox(thread_callback,thread_env,unpack(thread.data)) + if not success then error(err) end + return err + else + local success, err = Manager.sandbox(thread_callback,{},env,unpack(thread.data)) + if not success then error(err) end + return err + end + end) + -- opens the thread and then queues it + use_thread:open() + Server.queue_thread(use_thread) + else + local _callback = callback + if not is_type(callback,'function') then + local rtn, err = loadstring(callback) + if err then return false, err end + _callback = rtn + end + if is_type(env,'table') and not is_type(env.__self,'userdata') and env._env == true then + local success, err = Manager.sandbox(_callback,env,...) + if not success then return success,err + else return success, unpack(err) end + else + local success, err = Manager.sandbox(_callback,{},env,...) + if not success then return success,err + else return success, unpack(err) end + end + end +end + +--- The class for the server threads, allows ability to run async function +-- @type Thread +-- @alias Server._thread +-- @field name the name that is given to the thread, use for easy later indexing +-- @field timeout the time in ticks that the thread will have before it times out +-- @field reopen when true the thread will reopen itself until set to false, combine with timeout to create a long on_nth_tick wait +-- @field data any data that the thread will be able to access +Server._thread = {} + +local _env_metatable = { + __index=function(tbl,key) if rawget(tbl,'_modules') and tbl._modules[key] then return require(tbl._modules[key]) else return rawget(_G,key) end end +} + +--- Returns a new thread object +-- @usage new_thread = thread:create() +-- @tparam[opt={}] table obj all values are opt {timeout=int,name=str,data=any} +-- @treturn Server._thread the new thread object +function Server._thread.create(obj) + obj = obj or {} + setmetatable(obj,{__index=Server._thread}) + obj.uuid = tostring(Server.uuid) + -- creates a variable containing all upvalus for the thread (stops desyncs) + obj._env = get_upvalues(2) + obj._env._env = true + obj._env._ENV = nil -- prevents infinite recursion + -- removes any modules from the _env to save space in global (less time to serialize) + obj._env._modules = {} + for name,value in pairs(obj._env) do if is_type(value,'table') and value._moduleName and loaded_modules[value._moduleName] == value then obj._env._modules[name] = value._moduleName obj._env[name] = nil end end + setmetatable(obj._env,_env_metatable) + local name = obj.name or 'Anon' + verbose('Created new thread: '..name..' ('..obj.uuid..')') + return obj +end + +--- Opens and queues a thread +-- @usage Server._thread:queue() -- returns true/false +-- @treturn boolean was the thread queued successfully +-- @see Server.queue_thread +function Server._thread:queue() + self:open() + return Server.queue_thread(self) +end + +--- Test if the thread has all required parts +-- @usage if thread:valid() then end -- basic test for valid +-- @tparam[opt=false] boolean skip_location_check true to skip the location checking +-- @treturn boolean is the thread valid +function Server._thread:valid(skip_location_check) + 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(global.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 + -- all above must be true to be valid, must accept nil and function + return true + end + return false +end + +--- Opens the thread; indexes this thread in the global index +-- @usage thread:open() -- return true +-- @treturn boolean if the thread was opened successfully +function Server._thread:open() + -- if the thread is valid and not already opened + if not self:valid(true) or self.opened then return false end + local uuid = self.uuid + -- sets the thread to open, this is the tick it was opened + self.opened = game.tick + -- creates the global index + global.all[uuid] = global.all[uuid] or self + global.all._n = global.all._n+1 + -- indexes the thread in other places if it has more function + -- if it was paused before (ie did not run any events) then the index is removed from the paused index + if global.paused[self.name] then global.paused[self.name] = nil end + -- if it has a timeout or on_tick handler then it is indexed in those indexes + if is_type(self.timeout,'number') then table.insert(global.timeout,uuid) end + if is_type(self._tick,'function') then table.insert(global.tick,uuid) end + -- if the thread is given a name then a index from the name to uuid is made + if is_type(self.name,'string') then global.named[self.name] = global.named[self.name] or self.uuid end + -- if there are event handlers then it will loop over them and add them to the event index + if is_type(self._events,'table') then + table.each(self._events,function(callback,event,global,uuid) + -- cant be used V + --Server.add_thread_handler(event) + if not global.events[event] then global.events[event] = {} end + table.insert(global.events[event],uuid) + end,global,self.uuid) + end + local name = self.name or 'Anon' + verbose('Opened thread: '..name..' ('..self.uuid..')') + return true +end + +--- Inverse of thread:open() - Removes all indexes to this thread, most cases this will cause it to become inaccessible +-- @usage thread:close() -- return true +-- @treturn boolean if the thread had a on_close function +function Server._thread:close() + local uuid = self.uuid + local _return = false + -- if there is a call to the threads on close event, will later return true + if is_type(self._close,'function') then Manager.sandbox(self._close,self._env,self) _return = true end + -- will search every possible location for this thread and remove it + local _,key = table.find(global.queue,function(v,k,uuid) return v == uuid end,uuid) + if key then table.remove(global.queue,key) end -- queue + _,key = table.find(global.timeout,function(v,k,uuid) return v == uuid end,uuid) + if key then table.remove(global.timeout,key) end -- timeouts + _,key = table.find(global.tick,function(v,k,uuid) return v == uuid end,uuid) + if key then table.remove(global.tick,key) end -- on_tick + -- then will look for it in the event handlers and remove it if found + if is_type(self._events,'table') then + table.each(self._events,function(callback,event) + if global.events[event] then + local _,key = table.find(global.events[event],function(v,k,uuid) return v == uuid end,uuid) + if key then table.remove(global.events[event],key) end + -- cant be used V + --if #global.events[event] == 0 then Event.remove(event,Server.game_event) global.events[event] = nil end + end + end) + end + -- sets the thread to closed + self.opened=nil + -- unless the thread has a name or is assigned to be reopened + if self.reopen == true then self:open() else + -- if it has a name but not assigned to reopen then it will become 'paused' + if is_type(self.name,'string') then global.paused[self.name]=self.uuid + -- else it will just be wiped from the global index + else global.all[uuid] = nil global.all._n = global.all._n-1 end + end + local name = self.name or 'Anon' + verbose('Closed thread: '..name..' ('..self.uuid..')') + 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 boolean true if the thread called on_success or on_error +function Server._thread:resolve(...) + local _return = false + -- checks if the resolve handler is still present + if is_type(self._resolve,'function') then + local success, err = Manager.sandbox(self._resolve,self._env,self,...) + if success then + -- if it was successful then it will attempt to call the success handler + if is_type(self._success,'function') then + -- interface is used as a way to delay the success call till the next tick + Server.interface(function(thread,err) + local _success, _err = Manager.sandbox(thread._success,thread._env,thread,err) + if not _success then thread:error(_err) end + end,true,self,err) + -- later returns true if there was a call to the success handler + _return = true + end + -- if there is an error the thread is asked to deal with it, returns true/false based on result of handler + else _return = self:error(err) end + end + -- closes the thread as it is no longer needed as its command has be ran + self:close() + return _return +end + +--- Checks the timeout on a thread - if timed out then it calls on_timeout and closes +-- @usage thread:check_timeout() -- return true +-- @treturn boolean if the thread timed out +function Server._thread:check_timeout() + local _return = false + -- makes sure the thread is still valid + if not self:valid() then return false end + -- checks if the thread has been opened longer than its time out period + if is_type(self.timeout,'number') and game.tick >= (self.opened+self.timeout) then + if is_type(self._timeout,'function') then + -- we do not care if the time out has caused an error as it is in most cases an error in its own right + Manager.sandbox(self._timeout,self._env,self) + end + _return = true + -- closes the thread to prevent any further event calls + self:close() + end + return _return +end + +--- Used to check and raise the error handler of the thread, if not present it raises an error +-- @usage thread:error(err) -- return true +-- @tparam string err the err to be raised +-- @treturn boolean did the thread have an error handler +function Server._thread:error(err) + local _return = false + if is_type(self._error,'function') then + Manager.sandbox(self._error,self._env,self,err) + _return = true + else + self:close() -- no matter what happens next this thread will be closed + error('Thread Error (no handler): '..err) + end + return _return +end + +--- Set function to run then an event is triggered, none of them are 'needed' but you are advised to have at least one +-- @usage thread:on_event('close',function) -- if event is not one below then a game event is used +-- @usage thread_only_events = ['close','timeout','tick','resolve','success','error'] +-- @tparam ?string|index event the name of the event that the function should be called on +-- @tparam function callback the function which is called by the event trigger +-- @treturn table returns self so that they can be chained together +function Server._thread:on_event(event,callback) + local events = {'close','timeout','tick','resolve','success','error'} + -- searches the above list for the event + local value = table.find(events,function(v,k,find) return v == string.lower(find) end,event) + if value and is_type(callback,'function') then + -- if it is a thread_only_event then it will add it to its core values + self['_'..value] = callback + elseif is_type(event,'number') and is_type(callback,'function') then + -- other wise it is appended to the event index of the thread + if not self._events then self._events = {} end + self._events[event] = callback + end + -- returns self to allowing chaining of on_event():on_event():on_event() etc.. + return self +end + +script.on_event(defines.events.on_tick,function(event) + -- uses its own on_tick event so that other actions can be tested for + if event.tick < 10 then return end + if #global.tick > 0 then Server.run_tick_threads() end -- on tick events + if #global.timeout > 0 then Server.check_timeouts() end -- timeout checks + if #global.queue > 0 then -- resolve one thread + local current_thread = global.all[global.queue[1]] + if current_thread and current_thread:valid() then current_thread:resolve() end + end +end) + +script.on_load(function(event) + -- sets up metatable again so that threads continue to work + for uuid,thread in pairs(Server.threads) do + setmetatable(thread,{__index=Server._thread}) + setmetatable(thread._env,_env_metatable) + end +end) + +function Server:on_init() + for name,id in pairs(defines.events) do if not script.get_event_handler(id) then script.on_event(id,Server._thread_handler) end end + if loaded_modules['ExpGamingCore.Command'] then verbose('ExpGamingCore.Command is installed; Loading commands src') require(module_path..'/src/commands',{Server=Server}) 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 variables eg: + Server.new_thread{ + name='tree-decon', + data={} + }: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):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):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):open() +]] \ No newline at end of file diff --git a/modules/ExpGamingCore/Server/softmod.json b/modules/ExpGamingCore/Server/softmod.json new file mode 100644 index 00000000..7c0ef190 --- /dev/null +++ b/modules/ExpGamingCore/Server/softmod.json @@ -0,0 +1,26 @@ +{ + "name": "ExpGamingCore.Server", + "version": "4.0.0", + "description": "Adds a thread system and event listening and a admin bypass (recommend to disable /c and use optional /interface)", + "location": "FSM_ARCHIVE", + "keywords": [ + "Library", + "Lib", + "ExpGaming", + "Core", + "Server", + "Thread", + "Interface", + "Events" + ], + "dependencies": { + "ExpGamingLib": "^4.0.0", + "FactorioStdLib.Table": "^0.8.0", + "FactorioStdLib.Color": "^0.8.0", + "FactorioStdLib.String": "^0.8.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Command": "?^4.0.0" + }, + "collection": "ExpGamingCore@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCore/Server/src/commands.lua b/modules/ExpGamingCore/Server/src/commands.lua new file mode 100644 index 00000000..4a0abf28 --- /dev/null +++ b/modules/ExpGamingCore/Server/src/commands.lua @@ -0,0 +1,49 @@ +--- Adds a thread system and event listening and a admin bypass (recommend to disable /c and use optional /interface) +-- @submodule ExpGamingCore.Server +-- @alias Server +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +--- This file will be loaded when ExpGamingCore.Command is present +-- @function _comment + +local Server = Server + +Server.interfaceCallbacks = {} +function Server.add_to_interface(loadAs,callback) Server.interfaceCallbacks[loadAs] = callback end + +function Server.add_module_to_interface(loadAs,moduleName) + local moduleName = moduleName or tostring(_G.moduleName) or nil + if not moduleName then error('No module name supplied for: '..loadAs,2) return end + Server.add_to_interface(loadAs,function() return require(moduleName) end) +end +Server.add_module_to_interface('Server','ExpGamingCore.Server') + +--- Runs the given input from the script +-- @command interface +-- @param code The code that will be ran +commands.add_command('interface','Runs the given input from the script', { + ['code']={true,'string-inf'} +}, function(event,args) + local callback = args.code + -- looks for spaces, if non the it will prefix the command with return + if not string.find(callback,'%s') and not string.find(callback,'return') then callback = 'return '..callback end + -- sets up an env for the command to run in + local env = {_env=true,} + if game.player then + env.player = game.player + env.surface = game.player.surface + env.force = game.player.force + env.position = game.player.position + env.entity = game.player.selected + env.tile = game.player.surface.get_tile(game.player.position) + end + -- adds custom callbacks to the interface + for name,custom_callback in pairs(Server.interfaceCallbacks) do env[name] = custom_callback() end + -- runs the function + local success, err = Server.interface(callback,false,env) + -- if there is an error then it will remove the stacktrace and return the error + if not success and is_type(err,'string') then local _end = string.find(err,':1:') if _end then err = string.sub(err,_end+4) end end + -- if there is a value returned that is not nill then it will return that value + if err or err == false then player_return(err) end +end) \ No newline at end of file diff --git a/modules/ExpGamingCore/Sync/control.lua b/modules/ExpGamingCore/Sync/control.lua new file mode 100644 index 00000000..bfd91b43 --- /dev/null +++ b/modules/ExpGamingCore/Sync/control.lua @@ -0,0 +1,337 @@ +--- Allows syncing with an outside server and info panel. +-- @module ExpGamingCore.Sync +-- @alias Sync +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') +local Color = require('FactorioStdLib.Color') + +local Sync = {} +local Sync_updates = {} +local module_verbose = false --true|false + +--- Global Table +-- @table global +-- @field server_name the server name +-- @field server_description a short description of the server +-- @field reset_time the reset time of the server +-- @field time the last known irl time +-- @field time_set the last in game time that the time was set +-- @field last_update the last time that this info was updated +-- @field time_period how often this information is updated +-- @field players a list of different player related states +-- @field ranks a list of player ranks +-- @field rockets the number of rockets launched +-- @field mods the mods which are loaded +local global = global{ + server_name='Factorio Server', + server_description='A factorio server for everyone', + reset_time='On Demand', + time='Day Mth 00 00:00:00 UTC Year', + date='0000/00/00', + time_set={0,'0.00M'}, + last_update={0,'0.00M'}, + time_period={18000,'5.00M'}, + game_speed=1.0, + players={ + online={}, + n_online=0, + all={}, + n_all=0, + admins_online=0, + afk_players={}, + times={} + }, + roles={admin={online={},players={},n_online=0,n_players=0},user={online={},players={},n_online=0,n_players=0}}, + rockets=0, + mods={'Offline'} +} + +--- Player sub-table +-- @table global.players +-- @field online list of all players online +-- @field n_online the number of players online +-- @field all list of all player on or offline +-- @field n_all the number of players who have joined the server +-- @field admins_online the number of admins online +-- @field afk_players the number of afk players +-- @field times the play times of every player + +--- Used to standardise the tick format for any sync info +-- @usage Sync.tick_format(60) -- return {60,'1.00M'} +-- @treturn {number,string} table containing both the raw number and clean version of a time +function Sync.tick_format(tick) + if not is_type(tick,'number') then error('Tick was not given to Sync.tick_format',2) end + return {tick,tick_to_display_format(tick)} +end + +--- Prints to chat as if it were a player +-- @usage Sync.print('Test','Cooldude2606') +-- @tparam string player_message the message to be printed in chat +-- @tparam string player_name the name of the player sending the message +-- @tparam[opt] string player_tag the tag applied to the player's name +-- @tparam[opt] string player_colour the colour of the message, either hex or named colour +-- @tparam[opt] string prefix add a prefix before the chat eg [IRC] +function Sync.print(player_message,player_name,player_tag,player_colour,prefix) + if not player_message then error('No message given to Sync.print',2) end + local player = game.player or game.players[player_name] + local tag = player_tag and player_tag ~= '' and ' '..player_tag or '' + local colour = type(player_colour) == 'string' and player_colour or '#FFFFFF' + prefix = prefix and prefix..' ' or '' + -- if it is an in game player it will over ride the given params + if player then + tag = ' '..player.tag + colour = player.chat_color + player_name = player.name + else + -- converts colour into the accepted factorio version + if colour:find('#') then colour = Color.from_hex(colour) + else colour = defines.color[player_colour] end + end + game.print(prefix..player_name..tag..': '..player_message,colour) +end + +--- Outline of the parameters accepted by Sync.emit_embedded +-- @table EmitEmbededParamaters +-- @field title the tile of the embed +-- @field color the color given in hex you can use Color.to_hex{r=0,g=0,b=0} +-- @field description the description of the embed +-- @field server_detail sting to add onto the pre-set server detail +-- @field fieldone the filed to add to the embed (key is name) (value is text) (start value with <<inline>> to make inline) +-- @field fieldtwo the filed to add to the embed (key is name) (value is text) (start value with <<inline>> to make inline) + +--- Logs an embed to the json.data we use a js script to add things we cant here +-- @usage Sync.emit_embedded{title='BAN',color='0x0',description='A player was banned' ... } +-- @tparam table args a table which contains everything that the embedded will use +-- @see EmitEmbededParamaters +function Sync.emit_embedded(args) + if not is_type(args,'table') then error('Args table not given to Sync.emit_embedded',2) end + if not game then error('Game has not loaded',2) end + local title = is_type(args.title,'string') and args.title or '' + local color = is_type(args.color,'string') and args.color:find("0x") and args.color or '0x0' + local description = is_type(args.description,'string') and args.description or '' + local server_detail = is_type(args.server_detail,'string') and args.server_detail or '' + local mods_online = 'Mods Online: '..Sync.info.players.admins_online + -- creates the first field given for every emit + local done, fields = {title=true,color=true,description=true,server_detail=true}, {{ + name='Server Details', + value='Server Name: ${serverName} Online Players: '..#game.connected_players..' '..mods_online..' Server Time: '..tick_to_display_format(game.tick)..' '..server_detail + }} + -- for each value given in args it will create a new field for the embed + for key, value in pairs(args) do + if not done[key] then + done[key] = true + local f = {name=key,value='',inline=false} + -- if <> is present then it will cause the field to be inline if the previous + local value, inline = value:gsub("<>",'',1) + if inline > 0 then f.inline = true end + f.value = value + table.insert(fields,f) + end + end + -- forms the data that will be emitted to the file + local log_data = { + title=title, + description=description, + color=color, + fields=fields + } + game.write_file('embedded.json',table.json(log_data)..'\n',true,0) +end + +--- The error handle setup by sync to emit a discord embed for any errors +-- @local here +-- @function errorHandler +-- @tparam string err the error passed by the err control +error.addHandler('Discord Emit',function(err) + if not game then return error(error()) end + local color = Color and Color.to_hex(defines.textcolor.bg) or '0x0' + Sync.emit_embedded{title='SCRIPT ERROR',color=color,description='There was an error in the script @Developers ',Error=err} +end) + +--- Used to get the number of admins currently online +-- @usage Sync.count_admins() -- returns number +-- @treturn number the number of admins online +function Sync.count_admins() + -- game check + if not game then return 0 end + local _count = 0 + for _,player in pairs(game.connected_players) do + if player.admin then _count=_count+1 end + end + return _count +end + +--- Used to get the number of afk players defined by 2 min by default +-- @usage Sync.count_afk_times() +-- @tparam[opt=7200] int time in ticks that a player is called afk +-- @treturn number the number of afk players +function Sync.count_afk_times(time) + if not game then return 0 end + time = time or 7200 + local rtn = {} + for _,player in pairs(game.connected_players) do + if player.afk_time > time then rtn[player.name] = Sync.tick_format(player.afk_time) end + end + return rtn +end + +--- Used to get the number of players in each rank and currently online +-- @usage Sync.count_roles() +-- @treturn table contains the ranks and the players in that rank +function Sync.count_roles() + if not game then return {'Offline'} end + local _rtn = {admin={online={},players={}},user={online={},players={}}} + for index,player in pairs(game.players) do + if player.admin then + table.insert(_rtn.admin.players,player.name) + if player.connected then table.insert(_rtn.admin.online,player.name) end + else + table.insert(_rtn.user.players,player.name) + if player.connected then table.insert(_rtn.user.online,player.name) end + end + end + _rtn.admin.n_players,_rtn.admin.n_online=#_rtn.admin.players,#_rtn.admin.online + _rtn.user.n_players,_rtn.user.n_online=#_rtn.user.players,#_rtn.user.online + return _rtn +end + +--- Used to get a list of every player name with the option to limit to only online players +-- @usage Sync.count_players() +-- @tparam boolean online true will get only the online players +-- @treturn table table of player names +function Sync.count_players(online) + if not game then return {'Offline'} end + local _players = {} + local players = {} + if online then _players = game.connected_players else _players = game.players end + for k,player in pairs(_players) do table.insert(players,player.name) end + return players +end + +--- Used to get a list of every player name with the amount of time they have played for +-- @usage Sync.count_player_times() +-- @treturn table table indexed by player name, each value contains the raw tick and then the clean string +function Sync.count_player_times() + if not game then return {'Offline'} end + local _players = {} + for index,player in pairs(game.players) do + _players[player.name] = Sync.tick_format(player.online_time) + end + return _players +end + +--- used to get the global list that has been defined, also used to set that list +-- @usage Sync.info{server_name='Factorio Server 2'} -- returns true +-- @usage Sync.info -- table of info +-- @tparam[opt=nil] table set keys to be replaced in the server info +-- @treturn boolean success was the data set +Sync.info = setmetatable({},{ + __index=global, + __newindex=global, + __call=function(tbl,set) + if not is_type(set,'table') then return false end + for key,value in pairs(set) do global[key] = value end + return true + end, + __pairs=function(tbl) + tbl = global + local function next_pair(tbl,key) + local k, v = next(tbl, key) + if type(v) ~= nil then return k,v end + end + return next_pair, tbl, nil + end, + __ipairs=function(tbl) + tbl = global + local function next_pair(tbl, i) + i = i + 1 + local v = tbl[i] + if v then return i, v end + end + return next_pair, tbl, 0 + end +}) + +--- Called to update values inside of the info +-- @usage Sync.update() +-- @return all of the new info +function Sync.update() + local info = Sync.info + info.time_period[2] = tick_to_display_format(info.time_period[1]) + info.last_update[1] = game.tick + info.last_update[2] = tick_to_display_format(game.tick) + info.game_speed = game.speed + info.players={ + online=Sync.count_players(true), + n_online=#game.connected_players, + all=Sync.count_players(), + n_all=#game.players, + admins_online=Sync.count_admins(), + afk_players=Sync.count_afk_times(), + times=Sync.count_player_times() + } + info.roles = Sync.count_roles() + info.rockets = game.forces['player'].get_item_launched('satellite') + for key,callback in pairs(Sync_updates) do info[key] = callback() end + return info +end + +--- Adds a callback to be called when the info is updated +-- @usage Sync.add_update('players',function() return #game.players end) +-- @tparam string key the key that the value will be stored in +-- @tparam function callback the function which will return this value +function Sync.add_update(key,callback) + if game then return end + if not is_type(callback,'function') then return end + Sync_updates[key] = callback +end + +--- Outputs the curent server info into a file +-- @usage Sync.emit_data() +function Sync.emit_data() + local info = Sync.info + game.write_file('server-info.json',table.json(info),false,0) +end + +--- Updates the info and emits the data to a file +-- @usage Sync.emit_update() +function Sync.emit_update() + Sync.update() Sync.emit_data() +end + +--- Used to return and set the current IRL time; not very good need a better way to do this +-- @usage Sync.time('Sun Apr 1 18:44:30 UTC 2018') +-- @usage Sync.time -- string +-- @tparam[opt=nil] string set the date time to be set +-- @treturn boolean if the date time set was successful +Sync.time=add_metatable({},function(full,date) + local info = Sync.info + if not is_type(full,'string') then return false end + info.time = full + info.date = date + info.time_set[1] = Sync.tick_format(game.tick) + return true +end,function() local info = Sync.info return info.time..' (+'..(game.tick-info.time_set[1])..' Ticks)' end) + +-- will auto replace the file every 5 min by default +script.on_event('on_tick',function(event) + local time = Sync.info.time_period[1] + if (event.tick%time)==0 then Sync.emit_update() end +end) + +script.on_event('on_player_joined_game',Sync.emit_update) +script.on_event('on_pre_player_left_game',Sync.emit_update) +script.on_event('on_rocket_launched',Sync.emit_update) + +function Sync:on_init() + if loaded_modules['ExpGamingCore.Gui'] then verbose('ExpGamingCore.Gui is installed; Loading gui src') require(module_path..'/src/gui',{Sync=Sync,module_path=module_path}) end + if loaded_modules['ExpGamingCore.Server'] then require('ExpGamingCore.Server').add_module_to_interface('Sync','ExpGamingCore.Sync') end +end + +function Sync:on_post() + Sync.info{mods=table.keys(loaded_modules)} +end + +return Sync \ No newline at end of file diff --git a/modules/ExpGamingCore/Sync/softmod.json b/modules/ExpGamingCore/Sync/softmod.json new file mode 100644 index 00000000..c86e56dd --- /dev/null +++ b/modules/ExpGamingCore/Sync/softmod.json @@ -0,0 +1,27 @@ +{ + "name": "ExpGamingCore.Sync", + "version": "4.0.0", + "description": "Allows syncing with an outside server and info panle.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Library", + "Lib", + "ExpGaming", + "Core", + "Info", + "Sync", + "External", + "Discord" + ], + "dependencies": { + "ExpGamingLib": "^4.0.0", + "FactorioStdLib.Color": "^0.8.0", + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Table": "^0.8.0", + "ExpGamingCore.Role": "?^4.0.0", + "ExpGamingCore.Gui": "?^4.0.0", + "ExpGamingCore.Server": "?^4.0.0" + }, + "collection": "ExpGamingCore@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingCore/Sync/src/gui.lua b/modules/ExpGamingCore/Sync/src/gui.lua new file mode 100644 index 00000000..f01ebf2a --- /dev/null +++ b/modules/ExpGamingCore/Sync/src/gui.lua @@ -0,0 +1,106 @@ +--- Allows syncing with an outside server and info panel. +-- @submodule ExpGamingCore.Sync +-- @alias Sync +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +--- This file will be loaded when ExpGamingCore.Gui is present +-- @function _comment + +local Gui = require('ExpGamingCore.Gui') +local Sync = Sync -- this is to force sync to remain in the ENV + +local Sync_gui_functions = {} +local logo_sprite_path = 'file'..string.sub(module_path,2)..'/src/logo.png' + +--- Adds a element to the sever info gui +-- @usage Sync.add_to_gui('string') -- return true +-- @param element see examples before for what can be used, it can also be a return from Gui.inputs.add +-- @treturn boolean based on weather it was successful or not +function Sync.add_to_gui(element,...) + if game then return false end + if is_type(element,'function') then + table.insert(Sync_gui_functions,{'function',element,...}) + elseif is_type(element,'table') then + if element.draw then table.insert(Sync_gui_functions,{'gui',element}) + else table.insert(Sync_gui_functions,{'table',element}) end + else table.insert(Sync_gui_functions,{'string',element}) end + return true +end + +Sync.add_to_gui('Welcome to the Explosive Gaming community! This is one of many servers which we host.') +Sync.add_to_gui(function(player,frame) return 'This server\'s next reset: '..Sync.info.reset_time end) + +--- Formats a label to be a certain format +-- @local label_format +local function label_format(label,width) + label.style.width = width + label.style.align = 'center' + label.style.single_line = false +end + +--- Creates a center gui that will appear on join +-- @gui server-info +Sync.info_gui = Gui.center{ + name='server-info', + caption=logo_sprite_path, + tooltip='Basic info about the current server', + draw=function(self,frame) + frame.caption = '' + local info = Sync.info + frame = frame.add{type='flow',direction='vertical'} + local h_flow = frame.add{type='flow'} + h_flow.add{type='sprite',sprite=logo_sprite_path} + local v_flow = h_flow.add{type='flow',direction='vertical'} + h_flow.add{type='sprite',sprite=logo_sprite_path} + local _flow = v_flow.add{type='flow'} + label_format(v_flow.add{ + type='label', + caption=info.server_description,style='description_label' + },412) + Gui.bar(_flow,110) + label_format(_flow.add{ + type='label', + caption='Welcome To '..info.server_name, + style='caption_label' + },180) + Gui.bar(_flow,110) + Gui.bar(frame,600) + local _frame = frame + frame = frame.add{ + type='frame', + direction='vertical', + style='image_frame' + } + frame.style.width = 600 + local text_flow = frame.add{type='flow',direction='vertical'} + local button_flow = frame.add{type='table',column_count=3} + for _,element in pairs(table.deepcopy(Sync_gui_functions)) do + local _type = table.remove(element,1) + if _type == 'function' then + local success, err = pcall(table.remove(element,1),frame.player_index,frame,unpack(element)) + if not success then error(err) else + if is_type(err,'table') then + if element.draw then element:draw(button_flow).style.width = 195 + else label_format(text_flow.add{type='label',caption=err},585) end + else label_format(text_flow.add{type='label',caption=tostring(err)},585) end + end + elseif _type == 'gui' then element[1]:draw(button_flow).style.width = 195 + elseif _type == 'string' then label_format(text_flow.add{type='label',caption=tostring(element[1])},585) + elseif _type == 'table' then label_format(text_flow.add{type='label',caption=element[1]},585) end + end + _frame.add{ + type='label', + caption='Press Ecs or E to close; this is only visible once!', + style='fake_disabled_label' + }.style.font='default-small' +end} + +script.on_event(defines.events.on_gui_click,function(event) + local element = event.element + if element and element.valid and element.caption and element.caption == 'Press Ecs or E to close; this is only visible once!' then + Gui.center.clear(event) + end +end) + +script.on_event(defines.events.on_player_joined_game,function(event) Sync.info_gui(event) end) \ No newline at end of file diff --git a/modules/ExpGamingCore/Sync/src/logo.png b/modules/ExpGamingCore/Sync/src/logo.png new file mode 100644 index 00000000..cef59c4d Binary files /dev/null and b/modules/ExpGamingCore/Sync/src/logo.png differ diff --git a/modules/ExpGamingCore/softmod.json b/modules/ExpGamingCore/softmod.json new file mode 100644 index 00000000..4b2715eb --- /dev/null +++ b/modules/ExpGamingCore/softmod.json @@ -0,0 +1,24 @@ +{ + "name": "ExpGamingCore", + "version": "4.0.0", + "description": "Explosive Gaming Core Files", + "location": "FSM_ARCHIVE", + "keywords": [ + "Library", + "Lib", + "ExpGaming", + "Core" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "submodules": { + "ExpGamingCore.Gui": "4.0.0", + "ExpGamingCore.Server": "4.0.0", + "ExpGamingCore.Sync": "4.0.0", + "ExpGamingCore.Command": "4.0.0", + "ExpGamingCore.Group": "4.0.0", + "ExpGamingCore.Role": "4.0.0" + }, + "dependencies": {} +} diff --git a/modules/ExpGamingInfo/Readme/control.lua b/modules/ExpGamingInfo/Readme/control.lua new file mode 100644 index 00000000..55365037 --- /dev/null +++ b/modules/ExpGamingInfo/Readme/control.lua @@ -0,0 +1,132 @@ +--- Adds a readme gui to the game that contains useful information +-- @module ExpGamingInfo.Readme +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Gui = require('ExpGamingCore.Gui') + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Sync'] then require(module_path..'/src/sync') end + end +} + +-- Function Define +local function format_label(label) + label.style.maximal_width = 480 + label.style.single_line = false +end + +ThisModule.Gui = Gui.center{ + name='readme', + caption='utility/questionmark', + tooltip={'ExpGamingInfo-Readme.tooltip'} +}:add_tab('guildlines',{'ExpGamingInfo-Readme.guildlines-name'},{'ExpGamingInfo-Readme.guildlines-tooltip'},function(frame) + for i = 1,10 do + local style=nil; if i == 1 then style = 'caption_label' end + format_label(frame.add{ + type='label', + caption={'ExpGamingInfo-Readme.guildlines-line'..tostring(i)}, + style=style + }) + end +end):add_tab('chat',{'ExpGamingInfo-Readme.chat-name'},{'ExpGamingInfo-Readme.chat-tooltip'},function(frame) + format_label(frame.add{ + type='label', + caption={'ExpGamingInfo-Readme.chat-singleline'} + }) +end):add_tab('commands',{'ExpGamingInfo-Readme.commands-name'},{'ExpGamingInfo-Readme.commands-tooltip'},function(frame) + format_label(frame.add{ + type='label', + caption={'ExpGamingInfo-Readme.commands-singleline'} + }) + Gui.bar(frame,480) + local table = frame.add{name='command_table',type='table',column_count=2} + table.add{ + type='label', + caption={'ExpGamingInfo-Readme.commands-col1'}, + style='caption_label' + } + table.add{ + type='label', + caption={'ExpGamingInfo-Readme.commands-col2'}, + style='caption_label' + } + table.style.width = 480 + table.draw_vertical_lines = true + table.draw_horizontal_line_after_headers = true + for _,command in pairs(commands.get_commands(frame.player_index)) do + table.add{ + type='label', + caption='/'..command.name + } + local description = table.add{ + type='label', + caption=command.description, + } + description.style.maximal_width = 400 + description.style.single_line = false + end +end):add_tab('links',{'ExpGamingInfo-Readme.links-name'},{'ExpGamingInfo-Readme.links-tooltip'},function(frame) + local links={ + 'https://discord.explosivegaming.nl', + 'https://explosivegaming.nl', + 'http://steamcommunity.com/groups/tntexplosivegaming', + 'https://www.patreon.com/badgamernl', + 'https://wiki.explosivegaming.nl/' + } + local function format(text_box) + text_box.style.minimal_width=400 + text_box.read_only = true + text_box.word_wrap = true + text_box.selectable = true + end + for i,link in pairs(links) do + frame.add{ + type="label", + caption={'ExpGamingInfo-Readme.links-cap'..tostring(i)}, + style='caption_label' + } + format(frame.add{ + type='text-box', + text=link + }) + end +end):add_tab('servers',{'ExpGamingInfo-Readme.servers-name'},{'ExpGamingInfo-Readme.servers-tooltip'},function(frame) + format_label(frame.add{ + type='label', + caption={'ExpGamingInfo-Readme.servers-singleline'} + }) + Gui.bar(frame,480) + for i = 1,6 do + frame.add{ + type='label', + caption={'ExpGamingInfo-Readme.servers-format',tostring(i),{'ExpGamingInfo-Readme.servers-cap'..tostring(i)}}, + style='caption_label' + } + format_label(frame.add{ + type='label', + caption={'ExpGamingInfo-Readme.servers-des'..tostring(i)} + }) + end +end):add_tab('rules',{'ExpGamingInfo-Readme.rules-name'},{'ExpGamingInfo-Readme.rules-tooltip'},function(frame) + format_label(frame.add{ + type='label', + caption={'ExpGamingInfo-Readme.rules-singleline'} + }) + Gui.bar(frame,480) + for i = 1,20 do + format_label(frame.add{ + type='label', + caption={'ExpGamingInfo-Readme.rules-format',i,{'ExpGamingInfo-Readme.rules-rule'..tostring(i)}} + }) + end +end) + +-- Module Return +-- when called will open readme for that user +return setmetatable(ThisModule,{__call=function(self,...) self.Gui(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingInfo/Readme/locale/de.cfg b/modules/ExpGamingInfo/Readme/locale/de.cfg new file mode 100644 index 00000000..4fc2512b --- /dev/null +++ b/modules/ExpGamingInfo/Readme/locale/de.cfg @@ -0,0 +1,68 @@ +[ExpGamingInfo-Readme] +tooltip=Open the readme gui that opens when you first join. +guildlines-name=Guild Lines +guildlines-tooltip=These are the guildlines you should follow +guildlines-line1=Welcome to the Explosive Gaming Community! +guildlines-line2= +guildlines-line3=Here are some guidelines to keep this Server fun for everyone: +guildlines-line4=- Hacking / cheating / abusing bugs will not be tolerated. +guildlines-line5=- Be polite and use common sense. +guildlines-line6=- Nobody likes spam. That includes: Chat, Bots, unlimited Chests and Concrete. +guildlines-line7=- Do not remove stuff without even trying to talk / ask about it. +guildlines-line8=- Trains: LHD (Left hand drive), no Loops and use them for long distances. (- Trains are only allowed in LHD (Left Hand Drive). Train loops. UPDATE) +guildlines-line9= +guildlines-line10=If you have any questions about the rules, the server or the game in general, feel free to ask. Have Fun! +chat-name=How To Chat +chat-tooltip=How to chat in factorio with default key config +chat-singleline=Chatting can be difficult for new players because it’s different than other games! It’s very simple, the button you need to press is the “GRAVE/TILDE” key it’s located under the “ESC key”. If you would like to change the key go to your controls tab in options. The key you need to change is “Toggle Lua console” it’s located in the second column 2nd from bottom. +commands-name=Commands +commands-tooltip=These are the commands you can use +commands-singleline=These are the many diffrent custom commands you are able to use, the base game commands are not shown +commands-col1=Command Name +commands-col2=Command Help +links-name=Links +links-tooltip=Helpful links for ways to get in touch +links-cap1=Discord voice and chat server: +links-cap2=Our website: +links-cap3=Steam: +links-cap4=Patreon: +servers-name=Servers +servers-tooltip=Info on our other servers +servers-singleline=Welcome to the Explosive Gaming Community! S1-S3 are staggered resets. +servers-format=S__1__: __2__ +servers-cap1=Public +servers-des1=A place for all players, this map reset every 144H At 16:00 UTC. +servers-cap2=Public +servers-des2=A place for all players, this map reset every 144H At 16:00 UTC. +servers-cap3=Public +servers-des3=A place for all players, this map reset every 144H At 16:00 UTC. +servers-cap4=Modded +servers-des4=A modded server not much to say, just download the mods to play. Link on Discord for members. +servers-cap5=Events +servers-des5=Sometimes we hold events, may require a password, join discord for more info. +servers-cap6=Donator +servers-des6=For those people who have two much money and give us some. Anything goes per request. +rules-name=All Rules +rules-tooltip=A full list of rules for the server +rules-singleline=This is a full list of rules what must be followed, the guildlines will cover most points in here but for those who like to follow the rules word to word then here is the full list. +rules-format=__1__) __2__ +rules-rule1=Hacking/cheating, exploiting and abusing bugs is not allowed. +rules-rule2=Any bugs or exploits found should be reported. (no creative items) +rules-rule3=Do not disrespect any player in the server. +rules-rule4=Do not take every item frmo a belt or via logics request, share resources. +rules-rule5=Do not spam, this includes stuff such as chat spam, item spam, chest spam etc. +rules-rule6=Do not laydown or remove concrete or stone with bots without permission. +rules-rule7=Do not use active provider chests without permission. +rules-rule8=Do not use speakers on global or with alearts without permission. +rules-rule9=Do not remove/move major parts of the factory without permission. +rules-rule10=Do not walk in player random direction for no reason(to save map size). +rules-rule11=Do not remove stuff just because you dont like it, tell people first. +rules-rule12=Do not rotate belts, deactive belts with wires, or cause production to stop. +rules-rule13=Do not make train roundabouts. Or any loops of any kind. +rules-rule14=When using trains use the same size that others have used. +rules-rule15=Trains are Left Hand Drive (LHD) only. +rules-rule16=Do not complain about lag, low fps and low ups or other things like that. +rules-rule17=Do not ask for rank, our ranks are synced with discord, admins cant give ranks. +rules-rule18=Do not advertise other servers unless you are a trusted server owner. +rules-rule19=Report any one who breaks the rules. +rules-rule20=Use common sense and what an admin says goes. diff --git a/modules/ExpGamingInfo/Readme/locale/en.cfg b/modules/ExpGamingInfo/Readme/locale/en.cfg new file mode 100644 index 00000000..086261eb --- /dev/null +++ b/modules/ExpGamingInfo/Readme/locale/en.cfg @@ -0,0 +1,69 @@ +[ExpGamingInfo-Readme] +tooltip=Open the ReadMe if this is your first time joining. +guildlines-name=Guidelines +guildlines-tooltip=These are the guidelines everyone should follow +guildlines-line1=Welcome to the Explosive Gaming Community! +guildlines-line2=Here are some guidelines that everyone is obligated to follow. +guildlines-line3=!!!No rights can be derived from these guidelines as the full list of rules (another tab in this window) is valid / operative!!! +guildlines-line4=- Hacking / cheating / abusing bugs will not be tolerated. +guildlines-line5=- Be polite and use common sense. +guildlines-line6=- Spamming (in the form of chat, bots, unlimited chests and concrete) is not allowed. +guildlines-line7=- Do not remove stuff without asking your fellow players. +guildlines-line8=- Trains are only allowed in LHD (Left Hand Drive). No train loops! +guildlines-line9= +guildlines-line10=If you have any questions about our rules, the server or Factorio in general, feel free to ask your fellow players or our helpful team. Have fun! +chat-name=How To Chat +chat-tooltip=How to chat in Factorio with default key config +chat-singleline=Chatting can be difficult for new players because it’s different than other games! It’s very simple, the button you need to press is the “GRAVE/TILDE” key (which is located under the “ESC key”) - If you would like to change the key, go to your Controls tab in options. The key you need to change is “Toggle LUA console” +commands-name=Commands +commands-tooltip=Commands that you can use in ExplosiveGaming +commands-singleline=Custom commands that you can use. Base commands are not shown here. +commands-col1=Command Name +commands-col2=Command Help +links-name=Links +links-tooltip=Helpful links for ways to get in touch with us +links-cap1=Discord voice and chat server: +links-cap2=Our website: +links-cap3=Steam: +links-cap4=Patreon: +links-cap5=Our wiki: +servers-name=Servers +servers-tooltip=Info on our other servers +servers-singleline=Welcome to the Explosive Gaming Community! S1-S3 are staggered resets. +servers-format=S__1__: __2__ +servers-cap1=Public +servers-des1=A place for all players, this map resets every 144H At 16:00 UTC. +servers-cap2=Public +servers-des2=A place for all players, this map resets every 144H At 16:00 UTC. +servers-cap3=Public +servers-des3=A place for all players, this map resets every 144H At 16:00 UTC. +servers-cap4=Modded +servers-des4=A Modded server for all players. Link on Discord for members. +servers-cap5=Events +servers-des5=Server for events (everyone can join) - May require a password. Join Discord for more info +servers-cap6=Donator +servers-des6=For players who support us financially. Changes can be made per request. +rules-name=Rules +rules-tooltip=The full list of ExplosiveGaming rules. +rules-singleline=Although the guidelines cover most of our rules, the full list always have more priority and override any guideline. It is advised to be familiar with all rules to prevent warnings or bans. +rules-format=__1__) __2__ +rules-rule1=Hacking / cheating / abusing bugs will not be tolerated. +rules-rule2=Any bugs or exploits found should be reported to our team members. (excluding creative items) +rules-rule3=Do not disrespect any player in the server. +rules-rule4=Taking all items from a belt or logistics request is forbidden: sharing resources is mandatory. +rules-rule5=Spamming (in the form of chat, bots, unlimited chests and concrete) is not allowed. +rules-rule6=Do not lay down/remove concrete or stone with bots without permission. +rules-rule7=Do not use active provider chests without permission. +rules-rule8=Do not use speakers on global or with alerts without permission. +rules-rule9=Do not remove/move major parts of the factory without permission. +rules-rule10=Do not walk in random directions for no reason (to save map size and server resources). +rules-rule11=Do not remove stuff without asking your fellow players. +rules-rule12=Do not rotate belts, deactivate belts with wires, or cause production to stop. +rules-rule13=Do not make train roundabouts. Or any loops of any kind. +rules-rule14=When using trains, use the same size other players have used. +rules-rule15=Trains are Left Hand Drive (LHD) only. +rules-rule16=Do not complain about lag, low fps and low ups etc. +rules-rule17=Do not ask for ranks. Our ranks are synchronized with Discord, make sure to join us there. +rules-rule18=Do not advertise other servers unless you are a trusted server owner. +rules-rule19=Report players who break the rules. +rules-rule20=Use common sense and what an Admin says goes. diff --git a/modules/ExpGamingInfo/Readme/locale/fr.cfg b/modules/ExpGamingInfo/Readme/locale/fr.cfg new file mode 100644 index 00000000..45c6f9d0 --- /dev/null +++ b/modules/ExpGamingInfo/Readme/locale/fr.cfg @@ -0,0 +1,68 @@ +[ExpGamingInfo-Readme] +tooltip=Open the readme gui that opens when you first join. +guildlines-name=Guild Lines +guildlines-tooltip=These are the guildlines you should follow +guildlines-line1=Welcome to the Explosive Gaming Community! +guildlines-line2= +guildlines-line3=Here are some guidelines to keep this Server fun for everyone: +guildlines-line4=- Hacking / cheating / abusing bugs will not be tolerated. +guildlines-line5=- Be polite and use common sense. +guildlines-line6=- Nobody likes spam. That includes: Chat, Bots, unlimited Chests and Concrete. +guildlines-line7=- Do not remove stuff without even trying to talk / ask about it. +guildlines-line8=- Trains: LHD (Left hand drive), no Loops and use them for long distances. (- Trains are only allowed in LHD (Left Hand Drive). Train loops. UPDATE) +guildlines-line9= +guildlines-line10=If you have any questions about the rules, the server or the game in general, feel free to ask. Have Fun! +chat-name=How To Chat +chat-tooltip=How to chat in factorio with default key config +chat-singleline=Chatting can be difficult for new players because it’s different than other games! It’s very simple, the button you need to press is the “GRAVE/TILDE” key it’s located under the “ESC key”. If you would like to change the key go to your controls tab in options. The key you need to change is “Toggle Lua console” it’s located in the second column 2nd from bottom. +commands-name=Commands +commands-tooltip=These are the commands you can use +commands-singleline=These are the many diffrent custom commands you are able to use, the base game commands are not shown +commands-col1=Command Name +commands-col2=Command Help +links-name=Links +links-tooltip=Helpful links for ways to get in touch +links-cap1=Discord voice and chat server: +links-cap2=Our website: +links-cap3=Steam: +links-cap4=Patreon: +servers-name=Servers +servers-tooltip=Info on our other servers +servers-singleline=Welcome to the Explosive Gaming Community! +servers-format=S__1__: __2__ +servers-cap1=Public +servers-des1=A place for all players, this map reset every 24h. +servers-cap2=Standard +servers-des2=Before you play make sure you understand the game, reset every 48h. +servers-cap3=Pro +servers-des3=A pure mega base server, reset every 7 days and a password is needed to join. +servers-cap4=Modded +servers-des4=A modded server not much to say, just download the mods to play. Link on Discord for members. +servers-cap5=Events +servers-des5=Sometimes we hold events, may require a password, join discord for more info. +servers-cap6=Donator +servers-des6=For those people who have two much money and give us some. Anything goes per request. +rules-name=All Rules +rules-tooltip=A full list of rules for the server +rules-singleline=This is a full list of rules what must be followed, the guildlines will cover most points in here but for those who like to follow the rules word to word then here is the full list. +rules-format=__1__) __2__ +rules-rule1=Hacking/cheating, exploiting and abusing bugs is not allowed. +rules-rule2=Any bugs or exploits found should be reported. (no creative items) +rules-rule3=Do not disrespect any player in the server. +rules-rule4=Do not take every item frmo a belt or via logics request, share resources. +rules-rule5=Do not spam, this includes stuff such as chat spam, item spam, chest spam etc. +rules-rule6=Do not laydown or remove concrete or stone with bots without permission. +rules-rule7=Do not use active provider chests without permission. +rules-rule8=Do not use speakers on global or with alearts without permission. +rules-rule9=Do not remove/move major parts of the factory without permission. +rules-rule10=Do not walk in player random direction for no reason(to save map size). +rules-rule11=Do not remove stuff just because you dont like it, tell people first. +rules-rule12=Do not rotate belts, deactive belts with wires, or cause production to stop. +rules-rule13=Do not make train roundabouts. Or any loops of any kind. +rules-rule14=When using trains use the same size that others have used. +rules-rule15=Trains are Left Hand Drive (LHD) only. +rules-rule16=Do not complain about lag, low fps and low ups or other things like that. +rules-rule17=Do not ask for rank, our ranks are synced with discord, admins cant give ranks. +rules-rule18=Do not advertise other servers unless you are a trusted server owner. +rules-rule19=Report any one who breaks the rules. +rules-rule20=Use common sense and what an admin says goes. \ No newline at end of file diff --git a/modules/ExpGamingInfo/Readme/locale/nl.cfg b/modules/ExpGamingInfo/Readme/locale/nl.cfg new file mode 100644 index 00000000..cc54dbd3 --- /dev/null +++ b/modules/ExpGamingInfo/Readme/locale/nl.cfg @@ -0,0 +1,68 @@ +[ExpGamingInfo-Readme] +tooltip=Open de ReadMe wanneer je voor het eerst speelt. +guildlines-name=Richtlijnen +guildlines-tooltip=Dit zijn de richtlijnen die je moet volgen. +guildlines-line1=Welkom op de ExplosiveGaming community! +guildlines-line2= +guildlines-line3=Hier zijn een aantal richtlijnen die ieder speler moet volgen. +guildlines-line4=- Hacken / cheaten en bugs misbruiken is niet toegestaan. +guildlines-line5=- Wees aardig en gebruik je gezonde verstand. +guildlines-line6=- Spammen (in de zin van chat, kisten en beton) is niet toegestaan. +guildlines-line7=- Geen spullen verwijderen zonder toestemming van andere spelers. +guildlines-line8=- Treinen (LHD - Left Hand Drive) geen loops. (- Trains are only allowed in LHD (Left Hand Drive). Train loops. UPDATE) +guildlines-line9= +guildlines-line10=Als je vragen hebt over deze regels of over de server in algemeen, aarzel dan niet om contact op te nemen met onze staff. +chat-name=Chatten +chat-tooltip=Chatten in Factorio met standaard instellingen +chat-singleline=Chatten kan moeilijk zijn voor nieuwe spelers omdat de chatmechanisme in Factorio anders is dan andere spellen. Het is simpel: druk op de "GRAVE/TILDE" knop (locatie is onder de ESC knop). Als je deze knop wilt aanpassen, ga naar de Controls tab in Opties. De knop die je moet aanpassen is "Toggle LUA Console" +commands-name=Commands +commands-tooltip=Dit zijn de commands die je kunt gebruiken. +commands-singleline=Er zijn veel verschillende custom commands die je kunt gebruiken. Let er wel op dat basis commands hier niet zichtbaar zijn. +commands-col1=Commando naam +commands-col2=Commando hulp +links-name=Links +links-tooltip=Nuttige links om in contact te komen met de community +links-cap1=Discord server: +links-cap2=Onze website: +links-cap3=Steam: +links-cap4=Patreon: +servers-name=Servers +servers-tooltip=Info over onze andere servers +servers-singleline=Welkom op de ExplosiveGaming community! S1 tot en met S3 heeft geplande resets. +servers-format=S__1__: __2__ +servers-cap1=Openbaar +servers-des1=Server voor alle spelers, deze map reset elke 144 uur om 16:00 UTC. +servers-cap2=Openbaar +servers-des2=A place for all players, deze map reset elke 144 uur om 16:00 UTC. +servers-cap3=Openbaar +servers-des3=A place for all players, deze map reset elke 144 uur om 16:00 UTC. +servers-cap4=Modded +servers-des4=Een modded server voor alle spelers. Links zijn te vinden in de Discord server. +servers-cap5=Events +servers-des5=Server voor events. Links en wachtwoorden zijn te vinden in de Discord server. +servers-cap6=Donator +servers-des6=Voor de spelers die ons financieel ondersteunen. +rules-name=Alle regels +rules-tooltip=Een lijst met regels die van toepassing zijn op alle ExplosiveGaming servers. +rules-singleline=Dit is een lijst met alle regels. De richtlijnen behandelt de meeste punten, maar de volledige lijst is ook van toepassing. +rules-format=__1__) __2__ +rules-rule1=Hacken / cheaten en bugs misbruiken is niet toegestaan. +rules-rule2=Bugs of fouten horen gerapporteerd te worden aan de staff. +rules-rule3=Respecteer iedereen in de server. +rules-rule4=Pak niet alles uit een belt of via logistiekaanvragen: deel je middelen. +rules-rule5=Spammen (in de zin van chat, kisten en beton) is niet toegestaan. +rules-rule6=Bouw geen beton of steen met bots zonder toestemming. +rules-rule7=Gebruik geen actieve providerkist zonder toestemming. +rules-rule8=Gebruik geen speakers (globaal of met alerts) zonder toestemming. +rules-rule9=Verwijder geen grote delen van het fabriek zonder toestemming. +rules-rule10=Loop niet in willekeurige plekken zonder een reden (bespaart mapgrootte en server resources) +rules-rule11=Geen spullen verwijderen zonder toestemming van andere spelers. +rules-rule12=Draai de belts niet, deactiveer belts niet met draden en laat de productie niet stoppen. +rules-rule13=Maak geen treinrotondes of lussen. +rules-rule14=Gebruik de zelfde grootte treinen als andere spelers. +rules-rule15=Treinen zijn alleen LHD (Left Hand Drive) +rules-rule16=Klaag niet over de lag, lage FPS of lage UPS. +rules-rule17=Vraag niet om ranks: ranks zijn synchroon met onze Discord server. +rules-rule18=Maak geen reclame voor andere servers, tenzij je daarvoor bevoegd bent. +rules-rule19=Rapporteer spelers die de regels breken. +rules-rule20=Gebruik gezond verstand. diff --git a/modules/ExpGamingInfo/Readme/locale/sv-SE.cfg b/modules/ExpGamingInfo/Readme/locale/sv-SE.cfg new file mode 100644 index 00000000..5299c304 --- /dev/null +++ b/modules/ExpGamingInfo/Readme/locale/sv-SE.cfg @@ -0,0 +1,69 @@ +[ExpGamingInfo-Readme] +tooltip=Öppna ReadMe om det här är första gången du ansluter dig. +guildlines-name=Riktlinjer +guildlines-tooltip=Det här är riktlinjerna som alla bör följa +guildlines-line1=Välkommen till gemenskapen ExplosiveGaming! +guildlines-line2=Här är riktlinjerna som alla är tvingade att följa. +guildlines-line3=!!!No rights can be derived from these guidelines as the full list of rules (another tab in this window) is valid / operative!!! +guildlines-line4=- Dataintrång / fusk / missbruk av buggar kommer inte att tolereras. +guildlines-line5=- Var artig och använd sunt förnuft. +guildlines-line6=- Spam (genom chat, bottar, obegränsade kistor och betong) är inte tillåtet. +guildlines-line7=- Ta inte bort saker utan att fråga dina medspelare. +guildlines-line8=- Tåg är bara tillåtna med vänstertrafik. Inga tågloopar! +guildlines-line9= +guildlines-line10= Om du har frågor om reglerna, servern eller generelt om Factorio, känn dig fri att fråga dina medspelare eller vårat hjälpsamma team. Ha kul! +chat-name=Hur du chattar +chat-tooltip=Hur du chattar i Factorio med standardinställningar +chat-singleline=Att chatta kan vara svårt för nya spelare efterson det är annurlunda från andra spel. Det är väldigt enkelt, tangenten som du behöver trycka på är "ö".Om du vill byta det, gå in till "kontroller" och ändra tangent för "lua konsol". +commands-name=Kommandon +commands-tooltip=Kommandon som du kan använda i ExplosiveGaming +commands-singleline=Anpassade kommandon som du kan använda. Baskommandon visas inte här. +commands-col1=Kommandonamn +commands-col2=kommandohjälp +links-name=Länkar +links-tooltip=Hjälpfulla länkar som visar vägar att komma i kontakt med oss. +links-cap1=Discord röst- och chatserver: +links-cap2=Våran Webbadress : +links-cap3=Steam: +links-cap4=Patreon: +links-cap5=Vår wiki: +servers-name=Servrar +servers-tooltip=Information om våra servrar +servers-singleline=Välkommen till ExplosiveGamings gemenskap! S1-S3 har förskjutna återställningar (resets). +servers-format=S__1__: __2__ +servers-cap1=Offentlig +servers-des1=En plats för alla spelare, then här kartan återställs varje 144H, 16:00 UTC. +servers-cap2=Offentlig +servers-des2=En plats för alla spelare, then här kartan återställs varje 144H, 16:00 UTC. +servers-cap3=Offentlig +servers-des3=En plats för alla spelare, then här kartan återställs varje 144H, 16:00 UTC. +servers-cap4=Modifierad +servers-des4=En modifierad server för alla spelare. Länk i Discord för medlemmar. +servers-cap5=Evenemang +servers-des5=Server för evenemang (alla kan ansluta sig) - Kan kräva lösenord. Anslut dig till Discord för mer info. +servers-cap6=Donator +servers-des6=För spelare som stöder oss finansiellt. Ändringar kan göras på begäran. +rules-name=Regler +rules-tooltip=Den fullla listan över ExplosiveGamings regler. +rules-singleline=Även om riktlinjerna täcker de flesta av reglerna så har den fulla listan alltid prioritet och går alltid före riktlinjerna. Det är välbetänkt att vara bekant med alla reglerna för att förhindra varningar och bannlystningar. +rules-format=__1__) __2__ +rules-rule1=Dataintrång / fusk / missbruk av buggar kommer inte att tolereras. +rules-rule2=Buggar och utnyttjingssätt ska rapporteras till team-medlemmar (exkludera kreativa saker) +rules-rule3=Var inte respektlös mot någon annan spelare i servern. +rules-rule4=Att ta alla saker från ett bälte eller logistikbegäran är förbjudet: att dela med sig av resurserna är obligatoriskt. +rules-rule5=Spam (genom chat, bottar, obegränsade kistor eller betong) är inte tillåtet. +rules-rule6=Gör inga placeringar/borttagningar av betong eller sten med hjälp av bottar utan tillåtelse. +rules-rule7=Använd inte aktiva tillgångskistor utan tillåtelse. +rules-rule8=Använd inte globala högtalare eller varningar utan tillåtelse. +rules-rule9=Ta inte bort eller flytta huvuddelar av fabriken utan tillåtelse. +rules-rule10=Gå inte omkring i slumpvisa riktningar utan anledning (för att spara kartstorlek och serverresurser) +rules-rule11=Ta inte bort saker utan att fråga dina medspelare. +rules-rule12=Rotera inte bälten, deaktivera inte bälten med kabel och orsaka inte produktionsstop. +rules-rule13=Gör inte tågrondeller. Eller någon loop av något slag. +rules-rule14=Vid användning av tåg, använd samma storlek som andra spelare använt sig av. +rules-rule15=Tåg körs endast med vänstertrafik. +rules-rule16=Klaga inte om lag, låg fps, låg ups etc. +rules-rule17=Be inte om högre rang. Våra ranger är synkroniserade med Discord, se till att du ansluter dig till oss där. +rules-rule18=Gör inte reklam för andra servrar om du inte är en betrodd serverägare. +rules-rule19=Rapportera spelare som bryter mot reglerna. +rules-rule20=Använd sunt förnuft och vad en admin säger gäller. diff --git a/modules/ExpGamingInfo/Readme/softmod.json b/modules/ExpGamingInfo/Readme/softmod.json new file mode 100644 index 00000000..d824408e --- /dev/null +++ b/modules/ExpGamingInfo/Readme/softmod.json @@ -0,0 +1,23 @@ +{ + "name": "ExpGamingInfo.Readme", + "version": "4.0.0", + "description": "Adds a readme gui to the game that contains useful information", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Info", + "ExpGaming", + "Readme", + "New Player" + ], + "author": "", + "contact": "", + "license": "", + "dependencies": { + "ExpGamingCore.Gui": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Sync": "?^4.0.0" + }, + "submodules": {}, + "collection": "ExpGamingInfo@4.0.0" +} diff --git a/modules/ExpGamingInfo/Readme/src/sync.lua b/modules/ExpGamingInfo/Readme/src/sync.lua new file mode 100644 index 00000000..51c3c8da --- /dev/null +++ b/modules/ExpGamingInfo/Readme/src/sync.lua @@ -0,0 +1,14 @@ +local Sync = require('ExpGamingCore.Sync') +local Gui = require('ExpGamingCore.Gui') + +Sync.add_to_gui(Gui.inputs.add_button('readme-sync-guildlines','View Guildlines','View the guildlines in the readme',function(player,element) + Gui.center.open_tab(player,'readme','guildlines') +end)) + +Sync.add_to_gui(Gui.inputs.add_button('readme-sync-links','View Other Links','View the links in the readme',function(player,element) + Gui.center.open_tab(player,'readme','links') +end)) + +Sync.add_to_gui(Gui.inputs.add_button('readme-sync-rules','View All Rules','View the all rules in the readme',function(player,element) + Gui.center.open_tab(player,'readme','rules') +end)) \ No newline at end of file diff --git a/modules/ExpGamingInfo/Rockets/control.lua b/modules/ExpGamingInfo/Rockets/control.lua new file mode 100644 index 00000000..6edd2130 --- /dev/null +++ b/modules/ExpGamingInfo/Rockets/control.lua @@ -0,0 +1,104 @@ +--- Adds a rocket count gui to the game that shows milestones and average rocket time +-- @module ExpGamingInfo.Rockets +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Gui = require('ExpGamingCore.Gui') +local Game = require('FactorioStdLib.Game') + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Sync^4.0.0'] then require(module_path..'/src/sync') end + end +} + +-- Global Define +local global = global{ + update=0, + first=0, + _last=0, + last=0, + fastest=0, + milestones={m1=0,m2=0,m5=0,m10=0,m20=0,m50=0,m100=0,m200=0,m500=0,m1000=0,m2000=0,m5000=0} +} + +-- Function Define +ThisModule.Gui = Gui.left{ + name='rockets', + caption='item/rocket-silo', + tooltip={'ExpGamingInfo-Rockets.tooltip'}, + draw=function(self,frame) + frame.caption = {'ExpGamingInfo-Rockets.name'} + local player = Game.get_player(frame.player_index) + local satellites = player.force.get_item_launched('satellite') + local time = {'ExpGamingInfo-Rockets.nan'} + if satellites == 1 then time = tick_to_display_format(game.tick) + elseif satellites > 1 then time = tick_to_display_format((game.tick-global.first)/satellites) end + if satellites ~= global.update then + global.update = satellites + if global.first == 0 then global.first = game.tick end + global._last = global.last + global.last = game.tick + if global.last-global._last < global.fastest or global.fastest == 0 then global.fastest = global.last-global._last end + end + frame.add{ + type='label', + caption={'ExpGamingInfo-Rockets.sent',satellites} + } + frame.add{ + type='label', + caption={'ExpGamingInfo-Rockets.first',tick_to_display_format(global.first)} + } + frame.add{ + type='label', + caption={'ExpGamingInfo-Rockets.last',tick_to_display_format(global.last-global._last)} + } + frame.add{ + type='label', + caption={'ExpGamingInfo-Rockets.time',time} + } + frame.add{ + type='label', + caption={'ExpGamingInfo-Rockets.fastest',tick_to_display_format(global.fastest)} + } + frame.add{ + type='label', + caption={'ExpGamingInfo-Rockets.milestones'}, + style='caption_label' + } + local milestones = frame.add{ + type='flow', + direction='vertical' + } + for milestone,next_time in pairs(global.milestones) do + milestone = tonumber(milestone:match('%d+')) + if next_time == 0 and satellites == milestone then + global.milestones['m'..milestone] = global.last + next_time = global.last + Gui.left.open('rockets') + end + local _time = {'ExpGamingInfo-Rockets.nan'} + if next_time > 0 then _time = tick_to_display_format(next_time) end + milestones.add{ + type='label', + caption={'ExpGamingInfo-Rockets.format',tostring(milestone),_time} + } + if next_time == 0 then break end + end + end, + can_open=function(player) + if player.force.get_item_launched('satellite') > 0 then return true + else return {'ExpGamingInfo-Rockets.none'} end + end +} + +-- Event Define +script.on_event(defines.events.on_rocket_launched,function(event) Gui.left.update('rockets') end) + +-- Module Return +-- when called will toggle the gui for that player, updates gui if no player given +return setmetatable(ThisModule,{__call=function(self,...) self.Gui(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingInfo/Rockets/locale/de.cfg b/modules/ExpGamingInfo/Rockets/locale/de.cfg new file mode 100644 index 00000000..8fd5471e --- /dev/null +++ b/modules/ExpGamingInfo/Rockets/locale/de.cfg @@ -0,0 +1,12 @@ +[ExpGamingInfo-Rockets] +name=Raketeninfo +tooltip=Detailliste über gestartete Raketen. +none=Es wurden noch keine Rakten gestartet. +nan=NaN +sent=Gestartete Raketen: __1__ +first=Erster Start: __1__ +last=Dauer bis zum letzten Start: __1__ +time=Durchschnittliche Starzeit: __1__ +fastest=Schnellster Start: __1__ +milestones=Meilensteine: +format=__1__: __2__ \ No newline at end of file diff --git a/modules/ExpGamingInfo/Rockets/locale/en.cfg b/modules/ExpGamingInfo/Rockets/locale/en.cfg new file mode 100644 index 00000000..263d9b2c --- /dev/null +++ b/modules/ExpGamingInfo/Rockets/locale/en.cfg @@ -0,0 +1,12 @@ +[ExpGamingInfo-Rockets] +name=Rocket Info +tooltip=List of details about the rockets sent. +none=No rockets have been sent yet. +nan=Not available +sent=Rockets Sent: __1__ +first=First Lanuched At: __1__ +last=Last Launch Took: __1__ +time=Average Launch Time: __1__ +fastest=Fastest Launch: __1__ +milestones=Milestones: +format=__1__: __2__ \ No newline at end of file diff --git a/modules/ExpGamingInfo/Rockets/locale/fr.cfg b/modules/ExpGamingInfo/Rockets/locale/fr.cfg new file mode 100644 index 00000000..344c368d --- /dev/null +++ b/modules/ExpGamingInfo/Rockets/locale/fr.cfg @@ -0,0 +1,12 @@ +[ExpGamingInfo-Rockets] +name=Rocket Info +tooltip=List of details about the rockets sent. +none=No rockets have been sent yet. +nan=NaN +sent=Rockets Sent: __1__ +first=First Lanuched At: __1__ +last=Last Launch Took: __1__ +time=Average Launch Time: __1__ +fastest=Fastest Launch: __1__ +milestones=Milestones: +format=__1__: __2__ \ No newline at end of file diff --git a/modules/ExpGamingInfo/Rockets/locale/nl.cfg b/modules/ExpGamingInfo/Rockets/locale/nl.cfg new file mode 100644 index 00000000..2fee0a06 --- /dev/null +++ b/modules/ExpGamingInfo/Rockets/locale/nl.cfg @@ -0,0 +1,12 @@ +[ExpGamingInfo-Rockets] +name=Raket Info +tooltip=Lijst met details over de verstuurde raketten. +none=Er zijn nog geen raketten verstuurd. +nan=Niet beschikbaar +sent=Raketten verstuurd: __1__ +first=Eerste raket gelanceerd op: __1__ +last=Meest recente lancering: __1__ +time=Gemiddelde lanceertijd: __1__ +fastest=Snelste lancering: __1__ +milestones=Mijlpalen: +format=__1__: __2__ diff --git a/modules/ExpGamingInfo/Rockets/locale/sv-SE.cfg b/modules/ExpGamingInfo/Rockets/locale/sv-SE.cfg new file mode 100644 index 00000000..eb4d93bd --- /dev/null +++ b/modules/ExpGamingInfo/Rockets/locale/sv-SE.cfg @@ -0,0 +1,13 @@ + +[ExpGamingInfo-Rockets] +name=Raketinformation +tooltip=Lista över detaljerna kring skickade raketer. +none=Inga raketer har blivit skickade ännu. +nan=Inte tillgängligt +sent=Skickade raketer: __1__ +first=Första uppskjutningen skedde: __1__ +last=Senaste uppskjutningen tog: __1__ +time=Genomsnittlig uppskjutningstid: __1__ +fastest=Snabbaste uppskjutning: __1__ +milestones=Milstolpar: +format=__1__: __2__ diff --git a/modules/ExpGamingInfo/Rockets/softmod.json b/modules/ExpGamingInfo/Rockets/softmod.json new file mode 100644 index 00000000..10c6e3e8 --- /dev/null +++ b/modules/ExpGamingInfo/Rockets/softmod.json @@ -0,0 +1,23 @@ +{ + "name": "ExpGamingInfo.Rockets", + "version": "4.0.0", + "description": "Adds a rocket count gui to the game that shows milestones and average rocket time", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Info", + "ExpGaming", + "Rockets" + ], + "author": "", + "contact": "", + "license": "", + "dependencies": { + "ExpGamingCore.Gui": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingCore.Sync^4.0.0": "?*" + }, + "submodules": {}, + "collection": "ExpGamingInfo@4.0.0" +} diff --git a/modules/ExpGamingInfo/Rockets/src/sync.lua b/modules/ExpGamingInfo/Rockets/src/sync.lua new file mode 100644 index 00000000..82482eac --- /dev/null +++ b/modules/ExpGamingInfo/Rockets/src/sync.lua @@ -0,0 +1,20 @@ +local Sync = require('ExpGamingCore.Sync') +local global = global['ExpGamingInfo.Rockets'] + +Sync.add_update('rockets',function() + local _return = {} + local satellites = game.forces.player.get_item_launched('satellite') + local time = {'rockets.nan'} + if satellites == 1 then time = tick_to_display_format(game.tick) + elseif satellites > 1 then time = tick_to_display_format((game.tick-global.first)/satellites) end + _return.total = satellites + _return.first = Sync.tick_format(global.first) + _return.last = Sync.tick_format(global.last-global._last) + _return.time = Sync.tick_format(time) + _return.fastest = Sync.tick_format(global.fastest) + _return.milestones = {} + for milestone,next_time in pairs(global.milestones) do + _return.milestones[milestone] = Sync.tick_format(next_time) + end + return _return +end) \ No newline at end of file diff --git a/modules/ExpGamingInfo/Science/control.lua b/modules/ExpGamingInfo/Science/control.lua new file mode 100644 index 00000000..74118960 --- /dev/null +++ b/modules/ExpGamingInfo/Science/control.lua @@ -0,0 +1,105 @@ +--- Adds a science count gui to the game that shows total made and per minute +-- @module ExpGamingInfo.Science +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Gui = require('ExpGamingCore.Gui') +local Game = require('FactorioStdLib.Game') + +-- Local Variables +local science_packs = { + 'science-pack-1', + 'science-pack-2', + 'science-pack-3', + 'military-science-pack', + 'production-science-pack', + 'high-tech-science-pack', + 'space-science-pack' +} + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Sync^4.0.0'] then require(module_path..'/src/sync',{science_packs=science_packs}) end + end +} + +-- Global Define +local global = global{ + _base={ + update=0, + _update=0, + made={0,0,0,0,0,0,0}, + _made={0,0,0,0,0,0,0} + } +} + +-- Function Define +ThisModule.Gui = Gui.left{ + name='science', + caption='item/lab', + tooltip={'ExpGamingInfo-Science.tooltip'}, + draw=function(self,frame) + local player = Game.get_player(frame.player_index) + if not global[player.force.name] then + verbose('Added Science Global for: '..player.force.name) + global[player.force.name] = table.deepcopy(global._base) + end + local force_data = global[player.force.name] + frame.caption = {'ExpGamingInfo-Science.name'} + frame.add{ + type='label', + caption={'ExpGamingInfo-Science.total'}, + style='caption_label' + } + local totals = frame.add{ + type='flow', + direction='vertical' + } + frame.add{ + type='label', + caption={'ExpGamingInfo-Science.time'}, + style='caption_label' + } + local times = frame.add{ + type='flow', + direction='vertical' + } + if force_data.update < game.tick-100 then + force_data._update = force_data.update + force_data._made = table.deepcopy(force_data.made) + for i,name in pairs(science_packs) do + force_data.made[i] = player.force.item_production_statistics.get_input_count(name) + end + force_data.update = game.tick + end + for i,name in pairs(science_packs) do + local made = force_data.made[i] + if made > 0 then + totals.add{ + type='label', + caption={'ExpGamingInfo-Science.format',{'ExpGamingInfo-Science.'..name},made} + } + local _made = string.format('%.2f',(made-force_data._made[i])/((force_data.update-force_data._update)/(3600*game.speed))) + times.add{ + type='label', + caption={'ExpGamingInfo-Science.format',{'ExpGamingInfo-Science.'..name},_made} + } + end + end + end, + can_open=function(player) + if player.force.item_production_statistics.get_input_count('science-pack-1') > 0 then return true + else return {'ExpGamingInfo-Science.none'} end + end +} + +-- Event Define +script.on_event(defines.events.on_research_finished,function(event) Gui.left.update('science') end) + +-- Module Return +-- when called will toggle the gui for that player, if no player it will update the gui +return setmetatable(ThisModule,{_call=function(self,...) self.Gui(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingInfo/Science/locale/de.cfg b/modules/ExpGamingInfo/Science/locale/de.cfg new file mode 100644 index 00000000..e10b31a4 --- /dev/null +++ b/modules/ExpGamingInfo/Science/locale/de.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Wissenschaftsinfo +tooltip=Detailliste über Wissenschaftspakete +total=Gemachte Pakete: +time=Pakete pro Minute: +format=__1__: __2__ +science-pack-1=Rot +science-pack-2=Grün +science-pack-3=Blau +military-science-pack=Militär +production-science-pack=Produktion +high-tech-science-pack=Hochtechnologie +space-science-pack=Weltraum +none=Es wurden noch keine Wissenschaftspakete gemacht. \ No newline at end of file diff --git a/modules/ExpGamingInfo/Science/locale/en.cfg b/modules/ExpGamingInfo/Science/locale/en.cfg new file mode 100644 index 00000000..a9bc1526 --- /dev/null +++ b/modules/ExpGamingInfo/Science/locale/en.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Science Info +tooltip=List of details about science packs. +total=Packs Made: +time=Packs Per Minute: +format=__1__: __2__ +science-pack-1=Red +science-pack-2=Green +science-pack-3=Blue +military-science-pack=Military +production-science-pack=Production +high-tech-science-pack=High Tech +space-science-pack=Space +none=No science packs have been made yet. \ No newline at end of file diff --git a/modules/ExpGamingInfo/Science/locale/fr.cfg b/modules/ExpGamingInfo/Science/locale/fr.cfg new file mode 100644 index 00000000..a9bc1526 --- /dev/null +++ b/modules/ExpGamingInfo/Science/locale/fr.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Science Info +tooltip=List of details about science packs. +total=Packs Made: +time=Packs Per Minute: +format=__1__: __2__ +science-pack-1=Red +science-pack-2=Green +science-pack-3=Blue +military-science-pack=Military +production-science-pack=Production +high-tech-science-pack=High Tech +space-science-pack=Space +none=No science packs have been made yet. \ No newline at end of file diff --git a/modules/ExpGamingInfo/Science/locale/nl.cfg b/modules/ExpGamingInfo/Science/locale/nl.cfg new file mode 100644 index 00000000..2ac8d7c0 --- /dev/null +++ b/modules/ExpGamingInfo/Science/locale/nl.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Wetenschap info +tooltip=Lijst met details over de wetenschaps pakketten. +total=Pakketten gemaakt: +time=Pakketten per minuut: +format=__1__: __2__ +science-pack-1=Rood +science-pack-2=Groen +science-pack-3=Blauw +military-science-pack=Militair +production-science-pack=Productie +high-tech-science-pack=High Tech +space-science-pack=Ruimte +none=Er zijn nog geen wetenschaps pakketten gemaakt. diff --git a/modules/ExpGamingInfo/Science/locale/sv-Se.cfg b/modules/ExpGamingInfo/Science/locale/sv-Se.cfg new file mode 100644 index 00000000..db40737c --- /dev/null +++ b/modules/ExpGamingInfo/Science/locale/sv-Se.cfg @@ -0,0 +1,14 @@ +[ExpGamingInfo-Science] +name=Vetenskapsinformation +tooltip=Detaljerad lista över vetenskapspaket. +total=Paket gjorda: +time=Paket per minut: +format=__1__: __2__ +science-pack-1=Röda +science-pack-2=Gröna +science-pack-3=Blåa +military-science-pack=Militära +production-science-pack=Produktion +high-tech-science-pack=Högteknologiska +space-science-pack=Rymd +none=Inga vetenskapspaket har blivit gjorda ännu. diff --git a/modules/ExpGamingInfo/Science/softmod.json b/modules/ExpGamingInfo/Science/softmod.json new file mode 100644 index 00000000..8f9cf99a --- /dev/null +++ b/modules/ExpGamingInfo/Science/softmod.json @@ -0,0 +1,24 @@ +{ + "name": "ExpGamingInfo.Science", + "version": "4.0.0", + "description": "Adds a science count gui to the game that shows toatal made and per minute", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Info", + "ExpGaming", + "Science", + "Production" + ], + "author": "", + "contact": "", + "license": "", + "dependencies": { + "ExpGamingCore.Gui": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingCore.Sync^4.0.0": "?*" + }, + "submodules": {}, + "collection": "ExpGamingInfo@4.0.0" +} diff --git a/modules/ExpGamingInfo/Science/src/sync.lua b/modules/ExpGamingInfo/Science/src/sync.lua new file mode 100644 index 00000000..6f624d4f --- /dev/null +++ b/modules/ExpGamingInfo/Science/src/sync.lua @@ -0,0 +1,19 @@ +local Sync = require('ExpGamingCore.Sync') +local data = global['ExpGamingInfo.Science'] +local science_packs = science_packs + +Sync.add_update('science',function() + local _return = {} + for force_name,global in pairs(data) do + if force_name ~= '_base' then + _return[force_name] = {totals={},times={}} + for i,name in pairs(science_packs) do + local made = global.made[i] + _return[force_name].totals[name] = made + local _made = string.format('%.2f',(made-global._made[i])/((global.update-global._update)/(3600*game.speed))) + _return[force_name].times[name] = _made + end + end + end + return _return +end) \ No newline at end of file diff --git a/modules/ExpGamingInfo/Tasklist/control.lua b/modules/ExpGamingInfo/Tasklist/control.lua new file mode 100644 index 00000000..5754742d --- /dev/null +++ b/modules/ExpGamingInfo/Tasklist/control.lua @@ -0,0 +1,206 @@ +--- Adds a task list gui which acts like a bulletin board for the current tasks +-- @module ExpGamingInfo.Tasklist +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Gui = require('ExpGamingCore.Gui') +local Role = require('ExpGamingCore.Role') +local Game = require('FactorioStdLib.Game') + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Global Define +local global = global{ + tasks={}, + _edit={}, + _base={ + _edit=false, + _tasks={}, + _editing={} + } +} + +-- Function Define +local edit = Gui.inputs{ + name='tasklist-edit', + type='button', + caption='utility/rename_icon_normal' +}:on_event('click',function(event) + local text_flow = event.element.parent.parent.text_flow + local data = global._edit[event.player_index] + if not data._edit then data._tasks = table.deepcopy(global.tasks) end + if text_flow.input.type == 'label' then + data._editing[tonumber(text_flow.parent.name)]=true + Gui.left.update('tasklist',event.player_index) + elseif text_flow.input.type == 'textfield' then + local text = text_flow.input.text + data._editing[tonumber(text_flow.parent.name)]=false + data._tasks[tonumber(text_flow.parent.name)]=text + Gui.left.update('tasklist',event.player_index) + end +end) + +local function _edit(frame) + local element = edit(frame) + element.style.height = 20 + element.style.width = 20 + local text_flow = element.parent.parent.text_flow + local data = global._edit[frame.player_index] + data._tasks[text_flow.parent.name]=text + if data._editing[tonumber(text_flow.parent.name)] then + element.style.height = 30 + element.style.width = 30 + local text = text_flow.input.caption + text_flow.clear() + local _text = text_flow.add{ + name='input', + type='textfield', + text=text + } + _text.style.width = 200 + element.sprite = 'utility/enter' + end +end + +local remove = Gui.inputs{ + name='tasklist-remove', + type='button', + caption='utility/remove' +}:on_event('click',function(event) + local frame = event.element.parent.parent + local data = global._edit[event.player_index] + if data._edit then + table.remove(data._tasks,tonumber(frame.name)) + table.remove(data._editing,tonumber(frame.name)) + else + table.remove(global.tasks,tonumber(frame.name)) + Gui.left.update('tasklist') + end + Gui.left.update('tasklist',event.player_index) +end) + +local add = Gui.inputs{ + name='tasklist-add', + type='button', + caption='utility/add' +}:on_event('click',function(event) + local frame = event.element.parent.parent + local data = global._edit[event.player_index] + if data._edit then + table.insert(data._tasks,tonumber(frame.name)+1,'New Value') + table.insert(data._editing,tonumber(frame.name)+1,true) + else + data._tasks = table.deepcopy(global.tasks) + table.insert(data._tasks,tonumber(frame.name)+1,'New Value') + table.insert(data._editing,tonumber(frame.name)+1,true) + end + Gui.left.update('tasklist',event.player_index) +end) + +local function _tasks(player) + player = Game.get_player(player) + local data = global._edit[player.index] + if not data then return global.tasks end + local editing = false + for _,v in pairs(data._editing) do + if v == true then + editing = true + break + end + end + if data._edit and not editing then + global.tasks = table.deepcopy(data._tasks) + global._edit[player.index] = table.deepcopy(global._base) + Gui.left.update('tasklist') + return global.tasks + elseif not data._edit and editing then + data._edit = true + for key,_ in pairs(data._tasks) do if not data._editing[key] then data._editing[key] = false end end + return data._tasks + elseif editing then return data._tasks + else return global.tasks + end +end + +ThisModule.Gui = Gui.left{ + name='tasklist', + caption='utility/not_enough_repair_packs_icon', + tooltip={'ExpGamingInfo-Tasklist.tooltip'}, + draw=function(self,frame) + frame.caption = '' + local title = frame.add{ + type='flow', + direction='horizontal' + } + title.add{ + type='label', + caption={'ExpGamingInfo-Tasklist.name'}, + style='caption_label' + } + local player = Game.get_player(frame.player_index) + local allowed = Role.allowed(player,'edit-tasklist') + if allowed then + if not global._edit[player.index] then global._edit[player.index] = table.deepcopy(global._base) end + end + for i,task in pairs(_tasks(player)) do + local flow = frame.add{ + name=i, + type='flow', + direction='horizontal' + } + local text_flow = flow.add{ + name='text_flow', + type='flow', + direction='horizontal' + } + text_flow.add{ + name='input', + type='label', + caption=task + } + local button_flow = flow.add{ + type='flow', + direction='horizontal' + } + if allowed then + _edit(button_flow) + if global._edit[player.index]._editing[i] then + local element = remove(button_flow) + element.style.height = 30 + element.style.width = 30 + local _element = add(button_flow) + _element.style.height = 30 + _element.style.width = 30 + end + end + end + if allowed then + local flow = title.add{ + name=#_tasks(player), + type='flow', + direction='horizontal' + } + local button_flow = flow.add{ + type='flow', + direction='horizontal' + } + local element = add(button_flow) + element.style.height = 20 + element.style.width = 20 + end + if #_tasks(player) == 0 and not allowed then frame.style.visible = false end + end, + can_open=function(player) + if Role.allowed(player,'edit-tasklist') or #global.tasks > 0 then return true + else return {'ExpGamingInfo-Tasklist.none'} end + end, + open_on_join=true +} + +-- Module return +-- when called it will toggle the gui for that player, if no player then it will update the gui +return setmetatable(ThisModule,{__call=function(self,...) self.Gui(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingInfo/Tasklist/locale/de.cfg b/modules/ExpGamingInfo/Tasklist/locale/de.cfg new file mode 100644 index 00000000..48573724 --- /dev/null +++ b/modules/ExpGamingInfo/Tasklist/locale/de.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Taskliste +tooltip=Welche Aufgaben müssen rund um die Fabrik erledigt werden? +none=Es sind aktuell keine Tasks erfasst, frage einen Member um einen hinzuzufügen. \ No newline at end of file diff --git a/modules/ExpGamingInfo/Tasklist/locale/en.cfg b/modules/ExpGamingInfo/Tasklist/locale/en.cfg new file mode 100644 index 00000000..7e698acf --- /dev/null +++ b/modules/ExpGamingInfo/Tasklist/locale/en.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Task List +tooltip=Jobs that needs to be completed all around the factory. +none=There are currently no tasks. Ask a Member in-game or through Discord to add tasks. \ No newline at end of file diff --git a/modules/ExpGamingInfo/Tasklist/locale/fr.cfg b/modules/ExpGamingInfo/Tasklist/locale/fr.cfg new file mode 100644 index 00000000..e739ac38 --- /dev/null +++ b/modules/ExpGamingInfo/Tasklist/locale/fr.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Task List +tooltip=What jobs need to be done round the factory. +none=There are no tasks to do right now, ask a member to add some. \ No newline at end of file diff --git a/modules/ExpGamingInfo/Tasklist/locale/nl.cfg b/modules/ExpGamingInfo/Tasklist/locale/nl.cfg new file mode 100644 index 00000000..6ab37662 --- /dev/null +++ b/modules/ExpGamingInfo/Tasklist/locale/nl.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Taaklijst +tooltip=Wat voor werk er rondom de fabriek gedaan moet worden +none=Er zijn momenteel geen taken. Vraag een Member om taken toe te voegen. diff --git a/modules/ExpGamingInfo/Tasklist/locale/sv-SE.cfg b/modules/ExpGamingInfo/Tasklist/locale/sv-SE.cfg new file mode 100644 index 00000000..5b0009bf --- /dev/null +++ b/modules/ExpGamingInfo/Tasklist/locale/sv-SE.cfg @@ -0,0 +1,4 @@ +[ExpGamingInfo-Tasklist] +name=Uppgiftslista +tooltip=Jobb som behövs slutföras överallt i fabriken +none=Det finns för närvarande inga uppgifter. Fråga en medlem i spelet eller via Discord för att lägga till nya uppgifter. \ No newline at end of file diff --git a/modules/ExpGamingInfo/Tasklist/softmod.json b/modules/ExpGamingInfo/Tasklist/softmod.json new file mode 100644 index 00000000..dcb673a7 --- /dev/null +++ b/modules/ExpGamingInfo/Tasklist/softmod.json @@ -0,0 +1,22 @@ +{ + "name": "ExpGamingInfo.Tasklist", + "version": "4.0.0", + "description": "Adds a task list gui which acts like a bulletin board for the current tasks", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Info", + "ExpGaming", + "Tasks" + ], + "author": "", + "contact": "", + "license": "", + "dependencies": { + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingCore.Role": "^4.0.0", + "FactorioStdLib.Game": "^0.8.0" + }, + "submodules": {}, + "collection": "ExpGamingInfo@4.0.0" +} diff --git a/modules/ExpGamingInfo/softmod.json b/modules/ExpGamingInfo/softmod.json new file mode 100644 index 00000000..fda8359b --- /dev/null +++ b/modules/ExpGamingInfo/softmod.json @@ -0,0 +1,21 @@ +{ + "name": "ExpGamingInfo", + "version": "4.0.0", + "description": "Adds info guis to the game for different production areas", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Info", + "ExpGaming", + "Production" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606@5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "submodules": { + "ExpGamingInfo.Readme": "4.0.0", + "ExpGamingInfo.Rockets": "4.0.0", + "ExpGamingInfo.Science": "4.0.0", + "ExpGamingInfo.Tasklist": "4.0.0" + } +} diff --git a/modules/ExpGamingLib/control.lua b/modules/ExpGamingLib/control.lua new file mode 100644 index 00000000..b68fb4a3 --- /dev/null +++ b/modules/ExpGamingLib/control.lua @@ -0,0 +1,321 @@ +--- Adds some common functions used though out all ExpGaming modules +-- @module ExpGamingLib +-- @alias ExpLib +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') +local Color = require('FactorioStdLib.Color') + +local module_verbose = false -- there is no verbose in this file so true will do nothing +local ExpLib = {} + +--- Loads a table into _G even when sandboxes; will not overwrite values or append to tables; will not work during runtime to avoid desyncs +-- @usage unpack_to_G{key1='foo',key2='bar'} +-- @tparam table tbl table to be unpacked +function ExpLib.unpack_to_G(tbl) + if not type(tbl) == 'table' or game then return end + for key,value in pairs(tbl) do + if not _G[key] then rawset(_G,key,value) end + end +end + +--- Used to get the current ENV with all _G keys removed; useful when saving function to global +-- @usage get_env() returns current ENV with _G keys removed +-- @treturn table the env table with _G keys removed +-- @warning does not work from console +function ExpLib.get_env(level) + level = level and level+1 or 2 + local env = setmetatable({},{__index=_G}) + while true do + if not debug.getinfo(level) then break end + local i = 1 + while true do + local name, value = debug.getlocal(level,i) + if not name or _G[name] == value then break else env[name] = value end + i=i+1 + end + level=level+1 + end + return env +end + +--- Used to get the current ENV with all _G keys removed; useful when saving function to global +-- @usage get_env() returns current ENV with _G keys removed +-- @treturn table the env table with _G keys removed +-- @warning does not work from console +function ExpLib.get_upvalues(level) + local func = level and ExpLib.is_type(level,'function') and level or nil + level = level and ExpLib.is_type(level,'number') and level+1 or 2 + func = func or debug.getinfo(level).func + local upvalues = setmetatable({},{__index=_G}) + local i = 1 + while true do + local name, value = debug.getupvalue(func,i) + if not name then break else upvalues[name] = value end + i=i+1 + end + return upvalues +end + +--- Creates a table that will act like a string and a function +-- @usage add_metatable({},function) -- returns table +-- @tparam table tbl the table that will have its metatable set +-- @tparam[opt=tostring] function callback the function that will be used for the call +-- @tparam[opt=table.tostring] ?function|string string a function that resolves to a string or a string +-- @treturn table the new table with its metatable set +function ExpLib.add_metatable(tbl,callback,string) + if not ExpLib.is_type(tbl,'table') then error('No table given to add_metatable',2) end + callback = ExpLib.is_type(callback,'function') and callback or tostring + string = ExpLib.is_type(string,'function') and string or ExpLib.is_type(string,'string') and function() return string end or table.tostring + return setmetatable(tbl,{ + __tostring=string, + __concat=function(val1,val2) return type(val1) == 'string' and val1..string(val2) or string(val1)..val2 end, + __call=callback + }) +end + +--- Compare types faster for faster validation of prams +-- @usage is_type('foo','string') -- return true +-- @usage is_type('foo') -- return false +-- @param v the value to be tested +-- @tparam[opt=nil] string test_type the type to test for if not given then it tests for nil +-- @treturn boolean is v of type test_type +function ExpLib.is_type(v,test_type) + return test_type and v and type(v) == test_type or not test_type and not v or false +end + +--- Compare types faster for faster validation of prams, including giving an error if incorrect +-- @usage type_error('foo','string','Value is not a string') -- return true +-- @usage type_error('foo','table','Value is not a string') -- return error +-- @param value the value to be tested +-- @tparam[opt=nil] string type the type that the value should be +-- @tparam string error_message the message given when type is not matched +-- @treturn boolean if it matched or and error +function ExpLib.type_error(value,type,error_message) + return ExpLib.is_type(value,type) or error(error_message,3) +end + +--- A specialised version of type_error to test for self +-- @usage self_test(self,'Object','get_name') +-- @tparam table self the table that is the object +-- @tparam string prototype_name the name of the class +-- @tparam string function_name the name of the function +function ExpLib.self_test(self,prototype_name,function_name) + return ExpLib.is_type(self,'table') or error('Call to prototype without context, either supply a '..prototype_name..' or use '..prototype_name..':'..function_name,3) +end + +--- Will return a value of any type to the player/server console, allows colour for in-game players +-- @usage player_return('Hello, World!') -- returns 'Hello, World!' to game.player or server console +-- @usage player_return('Hello, World!','green') -- returns 'Hello, World!' to game.player with colour green or server console +-- @usage player_return('Hello, World!',nil,player) -- returns 'Hello, World!' to the given player +-- @param rtn any value of any type that will be returned to the player or console +-- @tparam[opt=defines.colour.white] ?defines.color|string colour the colour of the text for the player, ignored when printing to console +-- @tparam[opt=game.player] LuaPlayer player the player that return will go to, if no game.player then returns to server +function ExpLib.player_return(rtn,colour,player) + colour = ExpLib.is_type(colour,'table') and colour or defines.textcolor[colour] ~= defines.color.white and defines.textcolor[colour] or defines.color[colour] + player = player or game.player + local function _return(callback,rtn) + if ExpLib.is_type(rtn,'table') then + -- test for: userdata, locale string, table with __tostring meta method, any other table + if ExpLib.is_type(rtn.__self,'userdata') then callback('Cant Display Userdata',colour) + elseif ExpLib.is_type(rtn[1],'string') and string.find(rtn[1],'.+[.].+') and not string.find(rtn[1],'%s') then callback(rtn,colour) + elseif getmetatable(rtn) ~= nil and not tostring(rtn):find('table: 0x') then callback(tostring(rtn),colour) + else callback(table.tostring(rtn),colour) end + -- test for: function + elseif ExpLib.is_type(rtn,'function') then callback('Cant Display Functions',colour) + -- else just call tostring + else callback(tostring(rtn),colour) end + end + if player then + -- allows any valid player identifier to be used + player = Game.get_player(player) + if not player then error('Invalid Player given to player_return',2) end + -- plays a nice sound that is different to normal message sound + player.play_sound{path='utility/scenario_message'} + _return(player.print,rtn) + else _return(rcon.print,rtn) end +end + +--- Convert ticks to hours +-- @usage tick_to_hour(216001) -- return 1 +-- @tparam number tick tick to convert to hours +-- @treturn number the number of whole hours from this tick +function ExpLib.tick_to_hour(tick) + if not ExpLib.is_type(tick,'number') then return 0 end + if not game then return math.floor(tick/216000) end + return math.floor(tick/(216000*game.speed)) +end + +--- Convert ticks to minutes +-- @usage tick_to_hour(3601) -- return 1 +-- @tparam number tick tick to convert to minutes +-- @treturn number the number of whole minutes from this tick +function ExpLib.tick_to_min (tick) + if not ExpLib.is_type(tick,'number') then return 0 end + if not game then return math.floor(tick/3600) end + return math.floor(tick/(3600*game.speed)) +end + +--- Converts a tick into a clean format for end user +-- @usage tick_to_display_format(3600) -- return '1.00 M' +-- @usage tick_to_display_format(234000) -- return '1 H 5 M' +-- @tparam number tick the tick to convert +-- @treturn string the formated string +function ExpLib.tick_to_display_format(tick) + if not ExpLib.is_type(tick,'number') then return '0H 0M' end + if ExpLib.tick_to_min(tick) < 10 then + if not game then return math.floor(tick/3600) end + return string.format('%.2f M',tick/(3600*game.speed)) + else + return string.format('%d H %d M', + ExpLib.tick_to_hour(tick), + ExpLib.tick_to_min(tick)-60*ExpLib.tick_to_hour(tick) + ) + end +end + +--- Used as a way to view the structure of a gui, used for debugging +-- @usage Gui_tree(root) returns all children of gui recursively +-- @tparam LuaGuiElement root the root to start the tree from +-- @treturn table the table that describes the gui +function ExpLib.gui_tree(root) + if not ExpLib.is_type(root,'table') or not root.valid then error('Invalid Gui Element given to gui_tree',2) end + local tree = {} + for _,child in pairs(root.children) do + if #child.children > 0 then + if child.name then tree[child.name] = ExpLib.gui_tree(child) + else table.insert(tree,ExpLib.gui_tree(child)) end + else + if child.name then tree[child.name] = child.type + else table.insert(tree,child.type) end + end + end + return tree +end + +--- Extents the table class +-- @type table +-- @alias table + +--- Returns a value in a form able to be read as a value, any value to string +-- @usage table.val_to_str{a='foo'} -- return '"foo"' +-- @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.tostring(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, any key to string +-- @usage table.val_to_str{a='foo'} -- return '["a"]' +-- @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 table.tostring{k1='foo',k2='bar'} -- return '{["k1"]="foo",["k2"]="bar"}' +-- @tparam table tbl table to convert +-- @treturn string the converted table +function table.tostring(tbl) + if type(tbl) ~= 'table' then return tostring(tbl) end + 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 + +--- Similar to table.tostring but converts a lua table to a json one +-- @usage table.json{k1='foo',k2='bar'} -- 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) + --if game and game.table_to_json then return game.table_to_json(lua_table) end + local result, done, only_indexes = {}, {}, 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 not value then table.insert(result,'null') + else table.insert(result,table.val_to_str(value)) + end + end + for key,value in pairs(lua_table) do + if not done[key] then + only_indexes = false + if type(value) == 'table' then table.insert(result,table.val_to_str(key)..':'..table.json(value,true)) + elseif not value then table.insert(result,table.val_to_str(key)..':null') + else table.insert(result,table.val_to_str(key)..':'..table.val_to_str(value)) + end + end + end + if only_indexes then return "["..table.concat(result,",").."]" + else return "{"..table.concat(result,",").."}" + end +end + +--- Returns the closest match to a key +-- @usage table.autokey({foo=1,bar=2},'f') -- return 1 +-- @tparam table tbl the table that will be searched +-- @tparam string str the string that will be looked for in the keys +function table.autokey(tbl,str) + if not ExpLib.is_type(str,'string') then return end + 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 + +--- Returns the list is a sorted way that would be expected by people (this is by key) +-- @usage tbl = table.alphanumsort(tbl) +-- @tparam table tbl the table to be sorted +-- @treturn table the sorted table +function table.alphanumsort(tbl) + local o = table.keys(tbl) + local function padnum(d) local dec, n = string.match(d, "(%.?)0*(.+)") + return #dec > 0 and ("%.12f"):format(d) or ("%s%03d%s"):format(dec, #n, n) end + table.sort(o, function(a,b) + return tostring(a):gsub("%.?%d+",padnum)..("%3d"):format(#b) + < tostring(b):gsub("%.?%d+",padnum)..("%3d"):format(#a) end) + local _tbl = {} + for _,k in pairs(o) do _tbl[k] = tbl[k] end + return _tbl +end + +--- Returns the list is a sorted way that would be expected by people (this is by key) (faster alterative than above) +-- @usage tbl = table.alphanumsort(tbl) +-- @tparam table tbl the table to be sorted +-- @treturn table the sorted table +function table.keysort(tbl) + local o = table.keys(tbl,true) + local _tbl = {} + for _,k in pairs(o) do _tbl[k] = tbl[k] end + return _tbl +end + +ExpLib:unpack_to_G() +return ExpLib \ No newline at end of file diff --git a/modules/ExpGamingLib/softmod.json b/modules/ExpGamingLib/softmod.json new file mode 100644 index 00000000..160803be --- /dev/null +++ b/modules/ExpGamingLib/softmod.json @@ -0,0 +1,19 @@ +{ + "name": "ExpGamingLib", + "version": "4.0.0", + "description": "Adds some common functions used though out all ExpGaming modules", + "location": "FSM_ARCHIVE", + "keywords": [ + "ExpGaming", + "Lib" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Color": "^0.8.0", + "FactorioStdLib.Table": "^0.8.0" + }, + "submodules": {} +} diff --git a/modules/ExpGamingPlayer/afkKick/control.lua b/modules/ExpGamingPlayer/afkKick/control.lua new file mode 100644 index 00000000..aa8f1c11 --- /dev/null +++ b/modules/ExpGamingPlayer/afkKick/control.lua @@ -0,0 +1,37 @@ +--- A full ranking system for factorio. +-- @module ExpGamingPlayer.afkKick@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') +local Role -- ExpGamingCore.Role@^4.0.0 +local Sync -- ExpGamingCore.Sync@^4.0.0 + +local function get_allowed_afk_time(player) + player = Game.get_player(player) + local role = Role and Role.get_highest(player) or {index=1,allow_afk_kick=not player.admin} + local player_count = #game.connected_players + local role_count = Role and Role.meta.count or 1 + local role_index = role.allow_afk_kick and role.index or false + if not role_index then return false end + return (role_count/role_index)*player_count +end + +script.on_event(defines.events.on_tick,function(event) + if (game.tick%3600) ~= 0 then return end + for _,player in pairs(game.connected_players) do + local afk = #game.connected_players < 3 and 10 or get_allowed_afk_time(player) + if afk then + if player.afk_time > afk*3600 then game.kick_player(player,'AFK For Too Long ('..math.floor(afk)..' Minutes)') end + end + end +end) + +return setmetatable({ + get_allowed_afk_time=get_allowed_afk_time, + on_init=function(self) + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + if loaded_modules['ExpGamingCore.Sync'] then Sync = require('ExpGamingCore.Sync') end + if loaded_modules['ExpGamingCore.Server'] then require(module_path..'/src/server',{Sync=Sync,self=self}) end + end +},{__call=function(self,...) return self.get_allowed_afk_time(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingPlayer/afkKick/softmod.json b/modules/ExpGamingPlayer/afkKick/softmod.json new file mode 100644 index 00000000..bace003d --- /dev/null +++ b/modules/ExpGamingPlayer/afkKick/softmod.json @@ -0,0 +1,22 @@ +{ + "name": "ExpGamingPlayer.afkKick", + "version": "4.0.0", + "description": "Adds a varible amount of time before a user is kicked based on the current player count.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Kick", + "AFK", + "Players", + "Smart", + "Varible" + ], + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingCore.Role": "?^4.0.0", + "ExpGamingCore.Sync": "?^4.0.0", + "ExpGamingCore.Server": "?^4.0.0" + }, + "collection": "ExpGamingPlayer@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingPlayer/afkKick/src/server.lua b/modules/ExpGamingPlayer/afkKick/src/server.lua new file mode 100644 index 00000000..ed6bcf00 --- /dev/null +++ b/modules/ExpGamingPlayer/afkKick/src/server.lua @@ -0,0 +1,29 @@ +local Sync = Sync +local get_allowed_afk_time = self +local Server = require('ExpGamingCore.Server') +local Color = require('FactorioStdLib.Color') +Event[defines.events.on_tick] = nil + +script.on_init(function(event) + Server.new_thread{ + name='afk-kick', + }:on_event('tick',function(self) + if (game.tick%3600) ~= 0 then return end + for _,player in pairs(game.connected_players) do + local afk = #game.connected_players < 3 and 10 or get_allowed_afk_time(player) + if afk then + if player.afk_time > afk*3600 then game.kick_player(player,'AFK For Too Long ('..math.floor(afk)..' Minutes)') end + end + end + end):on_event('error',function(self,err) + if Sync then + Sync.emit_embedded{ + title='Auto Kick Error', + color=Color.to_hex(defines.textcolor.bg), + description='Auto Kick Error - Closed Thread', + Error=err + } + end + self:close() + end):open() +end) diff --git a/modules/ExpGamingPlayer/inventorySearch/control.lua b/modules/ExpGamingPlayer/inventorySearch/control.lua new file mode 100644 index 00000000..12318f15 --- /dev/null +++ b/modules/ExpGamingPlayer/inventorySearch/control.lua @@ -0,0 +1,92 @@ +--- Adds an inventory search that is preformed on a random player every 15 seconds +-- @module ExpGamingPlayer.inventorySearch@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Admin = require('ExpGamingAdmin') +local Role -- ExpGamingCore.Role@^4.0.0 + +-- Local Variables +-- removed from none admin ranks, no further action +local low_items = { + 'loader', + 'fast-loader', + 'express-loader', + 'small-plane', + 'player-port', + 'coin', + 'programmable-speaker', + 'logistic-chest-active-provider' +} + +-- removed for admin and non-admin ranks, gives warnings to non-admins +local med_items = { + 'railgun', + 'railgun-dart', + 'belt-immunity-equipment' +} + +-- temp-ban for any rank, this is a very hard enforcement, admin ranks lose rank +local high_items = { + 'electric-energy-interface', + 'infinity-chest' +} + +-- inventories which are searched +local inventories = { + defines.inventory.player_main, + defines.inventory.player_quickbar, + defines.inventory.player_trash +} + +local _root_tree = {low_items=low_items,med_items=med_items,high_items=high_items} + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + end +} + +-- Function Define +local function take_action(player,item_name,category) + if category == 'low_items' then player_return({'ExpGamingPlayer-inventorySearch.low',item_name},defines.textcolor.med,player) + elseif category == 'med_items' then player_return({'ExpGamingPlayer-inventorySearch.med',item_name},defines.textcolor.high,player) Admin.give_warning(player,'','Found A Banned Item',5) + elseif category == 'high_items' then player_return({'ExpGamingPlayer-inventorySearch.high',item_name},defines.textcolor.crit,player) Admin.temp_ban(player,'','Found A Banned Item') + else return end +end + +function ThisModule.search_player(player) + for category,items in pairs(_root_tree) do + if not Role or category ~= 'low_items' and not Role.allowed(player,'admin-items') then + for _,_inventory in pairs(inventories) do + local inventory = player.get_inventory(_inventory) + if inventory then + for _,item in pairs(items) do + local found = inventory.remove(item) + if found > 0 then take_action(player,item,category) end + end + end + end + end + end +end + +-- Event Handlers Define +script.on_event(defines.events.on_tick,function(event) + if (game.tick%900) == 0 then + local players = game.connected_players + if #players == 0 then return end + local player = players[math.random(#players)] + if Role and Role.allowed(player,'all-items') then return end + ThisModule.search_player(player) + end +end) + +-- Module Return +return setmetatable(ThisModule,{ + __call=function(self,...) self.search_player(...) end +}) \ No newline at end of file diff --git a/modules/ExpGamingPlayer/inventorySearch/locale/de.cfg b/modules/ExpGamingPlayer/inventorySearch/locale/de.cfg new file mode 100644 index 00000000..895707f4 --- /dev/null +++ b/modules/ExpGamingPlayer/inventorySearch/locale/de.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Dein Inventar wurde durchsucht und __1__ wurde entfernt. +med=Dein Inventar wurde durchsucht und __1__ wurde entfernt. Dir wird hiermit eine Warnung erteilt! Versuche es nicht erneut! +high=Dein inventar wurde durchsucht und __1__ wurde gefunden, dies ist auf GAR KEINEN Fall erlaubt, dein Inventar wurde zum Spawnpunkt transferiert. \ No newline at end of file diff --git a/modules/ExpGamingPlayer/inventorySearch/locale/en.cfg b/modules/ExpGamingPlayer/inventorySearch/locale/en.cfg new file mode 100644 index 00000000..0c45c5b1 --- /dev/null +++ b/modules/ExpGamingPlayer/inventorySearch/locale/en.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Your inventory was searched and __1__ was removed. +med=Your inventory was searched and __1__ was removed, you have been given a warning as a result. +high=Your inventory was searched and __1__ was removed: this is NOT allowed. You have been temp-banned as a result. \ No newline at end of file diff --git a/modules/ExpGamingPlayer/inventorySearch/locale/fr.cfg b/modules/ExpGamingPlayer/inventorySearch/locale/fr.cfg new file mode 100644 index 00000000..4d3eb1e4 --- /dev/null +++ b/modules/ExpGamingPlayer/inventorySearch/locale/fr.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Your Inventory Was Search And __1__ was removed. +med=Your Inventory Was Search And __1__ was removed, you have been given a warning. +high=Your Inventory Was Search And __1__ was found, this is not allowed AT ALL, your inventory has been moved to spawn. \ No newline at end of file diff --git a/modules/ExpGamingPlayer/inventorySearch/locale/nl.cfg b/modules/ExpGamingPlayer/inventorySearch/locale/nl.cfg new file mode 100644 index 00000000..2c6b6a60 --- /dev/null +++ b/modules/ExpGamingPlayer/inventorySearch/locale/nl.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Je inventaris is doorzocht en __1__ is verwijderd. +med=Je inventaris is doorzocht en __1__ is verwijderd, je bent gewaarschuwd. +high=Je inventaris is doorzocht en __1__ is gevonden, dit is ten strengste verboden! Je inventaris is verwijderd. diff --git a/modules/ExpGamingPlayer/inventorySearch/locale/sv-SE.cfg b/modules/ExpGamingPlayer/inventorySearch/locale/sv-SE.cfg new file mode 100644 index 00000000..ff5995b3 --- /dev/null +++ b/modules/ExpGamingPlayer/inventorySearch/locale/sv-SE.cfg @@ -0,0 +1,4 @@ +[ExpGamingPlayer-inventorySearch] +low=Ditt inventarie blev genomsökt och __1__ togs bort. +med=Ditt inventarie blev genomsökt och __1__ togs bort, du har fått en varning på grund av detta. +high=Ditt inventarie blev genomsökt och __1__ togs bort: Det här är inte tillåtet. Som ett resultat av det har du blivit tillfälligt bannlyst. diff --git a/modules/ExpGamingPlayer/inventorySearch/softmod.json b/modules/ExpGamingPlayer/inventorySearch/softmod.json new file mode 100644 index 00000000..17f251c0 --- /dev/null +++ b/modules/ExpGamingPlayer/inventorySearch/softmod.json @@ -0,0 +1,22 @@ +{ + "name": "ExpGamingPlayer.inventorySearch", + "version": "4.0.0", + "description": "Adds an inventory search that is proformed on a random player every 15 seconds.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Search", + "ExpGaming", + "Player", + "Inventory" + ], + "dependencies": { + "ExpGamingLib": "^4.0.0", + "ExpGamingAdmin.TempBan": "^4.0.0", + "ExpGamingAdmin.Warnings": "^4.0.0", + "ExpGamingCore.Role": "?^4.0.0", + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingAdmin": "^4.0.0" + }, + "collection": "ExpGamingPlayer@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingPlayer/playerInfo/control.lua b/modules/ExpGamingPlayer/playerInfo/control.lua new file mode 100644 index 00000000..cd68d962 --- /dev/null +++ b/modules/ExpGamingPlayer/playerInfo/control.lua @@ -0,0 +1,58 @@ +--- Used to give so common info on a player as a lua table or a frame. +-- @module ExpGamingPlayer.playerInfo@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') +local Gui = require('ExpGamingCore.Gui') +local Role -- ExpGamingCore.Role@^4.0.0 +local Group -- ExpGamingCore.Group@^4.0.0 + +local function get_player_info(player,frame,add_cam) + player = Game.get_player(player) + if not player then return {} end + local _player = {} + _player.index = player.index + _player.name = player.name + _player.online = player.connected + _player.tag = player.tag + _player.color = player.color + _player.admin = player.admin + _player.online_time = player.online_time + _player.group = player.permission_group.name + if Role then + _player.highest_role = Role.get_highest(player).name + local roles = {}; for _,role in pairs(Role.get(player)) do table.insert(roles,role.name) end + _player.roles = roles + end + if frame then + frame = frame.add{type='frame',direction='vertical',style='image_frame'} + frame.style.width = 200 + if Role then frame.style.height = 300 + else frame.style.height = 260 end + frame.add{type='label',caption={'ExpGamingPlayer-playerInfo.name',_player.index,_player.name},style='caption_label'} + local _online = {'ExpGamingPlayer-playerInfo.no'}; if _player.online then _online = {'ExpGamingPlayer-playerInfo.yes'} end + frame.add{type='label',caption={'ExpGamingPlayer-playerInfo.online',_online,tick_to_display_format(_player.online_time)}} + local _admin = {'ExpGamingPlayer-playerInfo.no'}; if _player.admin then _admin = {'ExpGamingPlayer-playerInfo.yes'} end + frame.add{type='label',caption={'ExpGamingPlayer-playerInfo.admin',_admin}} + if Role then + frame.add{type='label',caption={'ExpGamingPlayer-playerInfo.group',_player.group}} + frame.add{type='label',caption={'ExpGamingPlayer-playerInfo.role',_player.highest_role}} + frame.add{type='label',caption={'ExpGamingPlayer-playerInfo.roles',table.concat(_player.roles,', ')}}.style.single_line = false + end + if add_cam then + Gui.cam_link{entity=player.character,frame=frame,width=200,height=150,zoom=0.5,respawn_open=true} + end + end + return _player +end + +return setmetatable({ + get_player_info=get_player_info, + on_init=function(self) + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + if loaded_modules['ExpGamingCore.Group'] then Group = require('ExpGamingCore.Group') end + end +},{ + __call=function(self,...) return self.get_player_info(...) end +}) \ No newline at end of file diff --git a/modules/ExpGamingPlayer/playerInfo/locale/de.cfg b/modules/ExpGamingPlayer/playerInfo/locale/de.cfg new file mode 100644 index 00000000..1d52251f --- /dev/null +++ b/modules/ExpGamingPlayer/playerInfo/locale/de.cfg @@ -0,0 +1,8 @@ +[ExpGamingPlayer-playerInfo] +yes=Ja +no=Nein +name=[__1__] __2__ +online=Ist online: __1__ (__2__) +admin=Hat Admin Rang: __1__ +group=In Benutzer Gruppe: __1__ +role=Hat Rang: __1__ \ No newline at end of file diff --git a/modules/ExpGamingPlayer/playerInfo/locale/en.cfg b/modules/ExpGamingPlayer/playerInfo/locale/en.cfg new file mode 100644 index 00000000..4bbc1f12 --- /dev/null +++ b/modules/ExpGamingPlayer/playerInfo/locale/en.cfg @@ -0,0 +1,9 @@ +[ExpGamingPlayer-playerInfo] +yes=Yes +no=No +name=[__1__] __2__ +online=Is Online: __1__ (__2__) +admin=Has Admin: __1__ +group=In User Group: __1__ +role=Highest Role: __1__ +roles=Other Roles: __1__ \ No newline at end of file diff --git a/modules/ExpGamingPlayer/playerInfo/locale/fr.cfg b/modules/ExpGamingPlayer/playerInfo/locale/fr.cfg new file mode 100644 index 00000000..257168f7 --- /dev/null +++ b/modules/ExpGamingPlayer/playerInfo/locale/fr.cfg @@ -0,0 +1,8 @@ +[ExpGamingPlayer-playerInfo] +yes=Yes +no=No +name=[__1__] __2__ +online=Is Online: __1__ (__2__) +admin=Has Admin: __1__ +group=In User Group: __1__ +role=Has Rank: __1__ \ No newline at end of file diff --git a/modules/ExpGamingPlayer/playerInfo/locale/nl.cfg b/modules/ExpGamingPlayer/playerInfo/locale/nl.cfg new file mode 100644 index 00000000..931736ee --- /dev/null +++ b/modules/ExpGamingPlayer/playerInfo/locale/nl.cfg @@ -0,0 +1,8 @@ +[ExpGamingPlayer-playerInfo] +yes=Ja +no=Nee +name=[__1__] __2__ +online=Is Online: __1__ (__2__) +admin=Heeft Admin: __1__ +group=In Groep: __1__ +role=Heeft Rank: __1__ diff --git a/modules/ExpGamingPlayer/playerInfo/locale/sv-SE.cfg b/modules/ExpGamingPlayer/playerInfo/locale/sv-SE.cfg new file mode 100644 index 00000000..5a4406ae --- /dev/null +++ b/modules/ExpGamingPlayer/playerInfo/locale/sv-SE.cfg @@ -0,0 +1,8 @@ +[ExpGamingPlayer-playerInfo] +yes=Ja +no=Nej +name=[__1__] __2__ +online=Är Online: __1__ (__2__) +admin=Har Admin: __1__ +group=I användargrupp: __1__ +role=Har rang: __1__ diff --git a/modules/ExpGamingPlayer/playerInfo/softmod.json b/modules/ExpGamingPlayer/playerInfo/softmod.json new file mode 100644 index 00000000..2fda8414 --- /dev/null +++ b/modules/ExpGamingPlayer/playerInfo/softmod.json @@ -0,0 +1,21 @@ +{ + "name": "ExpGamingPlayer.playerInfo", + "version": "4.0.0", + "description": "Used to give so common info on a player as a lua table or a frame.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Cam", + "Follow", + "Player", + "Info", + "Useful" + ], + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingCore.Role": "?^4.0.0", + "ExpGamingCore.Group": "?^4.0.0" + }, + "collection": "ExpGamingPlayer@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingPlayer/playerList/control.lua b/modules/ExpGamingPlayer/playerList/control.lua new file mode 100644 index 00000000..886e3139 --- /dev/null +++ b/modules/ExpGamingPlayer/playerList/control.lua @@ -0,0 +1,144 @@ +--- A full ranking system for factorio. +-- @module ExpGamingPlayer.playerList@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') +local Gui = require('ExpGamingCore.Gui') +local Admin -- ExpGamingAdmin@^4.0.0 +local AdminGui -- ExpGamingAdmin.Gui@^4.0.0 + +-- Local Variables +local playerInfo = function(player,frame) + frame.add{ + type='label', + caption={'ExpGamingPlayer-playerList.no-info-file'} + } +end + +local getPlayers = function() + local rtn = {{{r=233,g=63,b=233},'Admin',{},true},{{r=255,g=159,b=27},'',{},false}} + for _,player in pairs(game.connected_players) do + if player.admin then table.insert(rtn[2][3],player) + else table.insert(rtn[1][3],player) end + end + return rtn +end + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function(self) + if loaded_modules['ExpGamingPlayer.playerInfo'] then playerInfo = require('ExpGamingPlayer.playerInfo') end + if loaded_modules['ExpGamingCore.Role'] then getPlayers = require(module_path..'/src/ranking',{self=self}) end + if loaded_modules['ExpGamingAdmin'] then Admin = require('ExpGamingAdmin') end + if loaded_modules['ExpGamingAdmin.Gui'] then AdminGui = require('ExpGamingAdmin.Gui') end + end +} + +-- Global Define +local global = global{ + update=0, + delay=10, + interval=54000 +} + +function ThisModule.update(tick) + local tick = is_type(tick,'table') and tick.tick or is_type(tick,'number') and tick or game.tick + if tick + global.delay > global.update - global.interval then + global.update = tick + global.delay + end +end + +local back_btn = Gui.inputs{ + type='button', + caption='utility/enter', + name='player-list-back' +}:on_event('click',function(event) + event.element.parent.parent.scroll.style.visible = true + event.element.parent.destroy() +end) + +ThisModule.Gui = Gui.left{ + name='player-list', + caption='entity/player', + tooltip={'ExpGamingPlayer-playerList.tooltip'}, + draw=function(self,frame) + frame.caption = '' + local player_list = frame.add{ + name='scroll', + type = 'scroll-pane', + direction = 'vertical', + vertical_scroll_policy='auto', + horizontal_scroll_policy='never' + } + player_list.vertical_scroll_policy = 'auto' + player_list.style.maximal_height=195 + local done = {} + local players = getPlayers() -- list of [colour,shortHand,[playerOne,playerTwo]] + for _,rank in pairs(players) do + for _,player in pairs(rank[3]) do + if not done[player.index] then + done[player.index] = true + local flow = player_list.add{type='flow'} + if rank[2] == '' then + flow.add{ + type='label', + name=player.name, + style='caption_label', + caption={'ExpGamingPlayer-playerList.format-nil',tick_to_display_format(player.online_time),player.name} + }.style.font_color = rank[1] + else + flow.add{ + type='label', + name=player.name, + style='caption_label', + caption={'ExpGamingPlayer-playerList.format',tick_to_display_format(player.online_time),player.name,rank[2]} + }.style.font_color = rank[1] + end + if Admin and Admin.report_btn then + if not rank[4] and player.index ~= frame.player_index then + local btn = Admin.report_btn(flow) + btn.style.height = 20 + btn.style.width = 20 + end + end + end + end + end + end, + open_on_join=true +} + +script.on_event(defines.events.on_tick,function(event) + if event.tick > global.update then + ThisModule.Gui() + global.update = event.tick + global.interval + end +end) + +script.on_event(defines.events.on_gui_click,function(event) + -- lots of checks for it being valid + if event.element and event.element.valid + and event.element.parent and event.element.parent.parent and event.element.parent.parent.parent + and event.element.parent.parent.parent.name == 'player-list' then else return end + -- must be a right click + if event.button == defines.mouse_button_type.right then else return end + local player_list = event.element.parent.parent.parent + -- must be a valid player which is clicked + if not Game.get_player(event.element.name) then return end + -- hides the player list to show the info + player_list.scroll.style.visible = false + local flow = player_list.add{type='flow',direction='vertical'} + back_btn:draw(flow) + playerInfo(event.element.name,flow,true) + if Game.get_player(event.element.name) and event.player_index == Game.get_player(event.element.name).index then return end + if Admin and AdminGui and Admin.allowed(event.player_index) then AdminGui(flow).caption = event.element.name end +end) + +script.on_event(defines.events.on_player_joined_game,function() ThisModule.update() end) +script.on_event(defines.events.on_player_left_game,function() ThisModule.update() end) + +ThisModule.force_update = function() return ThisModule.Gui() end +-- when called it will queue an update to the player list +return setmetatable(ThisModule,{__call=function(self,...) self.update(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingPlayer/playerList/locale/de.cfg b/modules/ExpGamingPlayer/playerList/locale/de.cfg new file mode 100644 index 00000000..ed48069f --- /dev/null +++ b/modules/ExpGamingPlayer/playerList/locale/de.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Verkleinere die Spielerliste. Rechtsklicke einen Spieler für Informationen über ihn. +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=Es wurden keine Informationen gefunden. \ No newline at end of file diff --git a/modules/ExpGamingPlayer/playerList/locale/en.cfg b/modules/ExpGamingPlayer/playerList/locale/en.cfg new file mode 100644 index 00000000..d2c2e345 --- /dev/null +++ b/modules/ExpGamingPlayer/playerList/locale/en.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Toggle player list, right click player for more info +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=No info file was found \ No newline at end of file diff --git a/modules/ExpGamingPlayer/playerList/locale/fr.cfg b/modules/ExpGamingPlayer/playerList/locale/fr.cfg new file mode 100644 index 00000000..83d2dd03 --- /dev/null +++ b/modules/ExpGamingPlayer/playerList/locale/fr.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Toogle player list, right click player for info +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=No info file was found \ No newline at end of file diff --git a/modules/ExpGamingPlayer/playerList/locale/nl.cfg b/modules/ExpGamingPlayer/playerList/locale/nl.cfg new file mode 100644 index 00000000..6a58e08a --- /dev/null +++ b/modules/ExpGamingPlayer/playerList/locale/nl.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Toggle speler lijst. Rechtermuisklik op een speler voor meer info +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=Geen infobestand gevonden. diff --git a/modules/ExpGamingPlayer/playerList/locale/sv-SE.cfg b/modules/ExpGamingPlayer/playerList/locale/sv-SE.cfg new file mode 100644 index 00000000..b871c389 --- /dev/null +++ b/modules/ExpGamingPlayer/playerList/locale/sv-SE.cfg @@ -0,0 +1,5 @@ +[ExpGamingPlayer-playerList] +tooltip=Växla spelarlista, högerklicka på spelare för mer information. +format-nil=__1__ - __2__ +format=__1__ - __2__ - __3__ +no-info-file=Ingen informationsfil kunde hittas diff --git a/modules/ExpGamingPlayer/playerList/softmod.json b/modules/ExpGamingPlayer/playerList/softmod.json new file mode 100644 index 00000000..bda73c47 --- /dev/null +++ b/modules/ExpGamingPlayer/playerList/softmod.json @@ -0,0 +1,24 @@ +{ + "name": "ExpGamingPlayer.playerList", + "version": "4.0.0", + "description": "Used to display player names and online time on the top left.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Player List", + "List", + "Gui", + "Names" + ], + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingCore.Role": "?^4.0.0", + "ExpGamingAdmin": "?^4.0.0", + "ExpGamingAdmin.buttonFlow": "?^4.0.0", + "ExpGamingAdmin.reports": "?^4.0.0", + "ExpGamingPlayer.playerInfo": "?^4.0.0", + "ExpGamingAdmin.Gui": "?^4.0.0" + }, + "collection": "ExpGamingPlayer@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingPlayer/playerList/src/ranking.lua b/modules/ExpGamingPlayer/playerList/src/ranking.lua new file mode 100644 index 00000000..66a94eae --- /dev/null +++ b/modules/ExpGamingPlayer/playerList/src/ranking.lua @@ -0,0 +1,15 @@ +local Role = require('ExpGamingCore.Role') + +script.on_event(defines.events.on_role_change,self.update) + +return function() + local rtn = {} + local default = {} + for _,role_name in pairs(Role.order) do + local role = Role.get(role_name) + if role.is_default then default = {role.colour,role.short_hand,role:get_players(true),role.not_reportable} + else table.insert(rtn,{role.colour,role.short_hand,role:get_players(true),role.not_reportable}) end + end + table.insert(rtn,default) + return rtn +end \ No newline at end of file diff --git a/modules/ExpGamingPlayer/polls/control.lua b/modules/ExpGamingPlayer/polls/control.lua new file mode 100644 index 00000000..1f187437 --- /dev/null +++ b/modules/ExpGamingPlayer/polls/control.lua @@ -0,0 +1,273 @@ +--- Adds a poll gui into the game for quick polls (default 90 seconds) +-- @module ExpGamingPlayer.polls@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +-- Module Require +local Server = require('ExpGamingCore.Server') +local Gui = require('ExpGamingCore.Gui') +local Role -- ExpGamingCore.Server@^4.0.0 + +-- Local Variables +local poll_time_out = 90 -- In seconds + +-- Module Define +local module_verbose = false +local ThisModule = { + on_init=function() + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + end +} + +-- Global Define +local global = global{ + active={}, + old={} +} + +-- Function Define +local function _poll_data(question,answers) + local rtn_poll = { + uuid=Server.uuid(), + question=question, + answers=answers or {'None'}, + votes={}, + voted={} + } + Server.new_thread{ + data={poll_uuid=rtn_poll.uuid}, + timeout=poll_time_out*60 + }:on_event('timeout',function(self) + local uuid = tostring(self.data.poll_uuid) + local poll = global.active[uuid] + if not poll then return end + local highest = {nil,-1} + local _votes = {} + for index,answer in pairs(poll.answers) do + local _result = poll.votes[index] or 0 + if _result > highest[2] then highest = {answer,_result} end + _votes[answer] = _result + end + poll.uuid = nil + poll.votes = _votes + poll.answers = nil + poll.voted = nil + table.insert(global.old,poll) + global.active[uuid] = nil + game.print({'ExpGamingPlayer-polls.end',poll.question},defines.textcolor.info) + game.print({'ExpGamingPlayer-polls.winner',highest[1]},defines.textcolor.info) + verbose('Ended Poll: '..poll.question..' ('..uuid..') Highest: '..highest[1]) + end):open() + global.active[tostring(rtn_poll.uuid)]=rtn_poll + verbose('Created Poll: '..question..' ('..rtn_poll.uuid..')') + return rtn_poll.uuid +end + +local function draw_poll(frame) + frame.clear() + local index = tonumber(frame.parent.current_index.caption) + local poll = global.old[index] + if not poll then + frame.add{ + type='label', + caption={'ExpGamingPlayer-polls.no-poll'} + } + return + end + frame.add{ + type='label', + caption='Question: '..poll.question + } + for answer,votes in pairs(poll.votes) do + frame.add{ + type='label', + caption=answer..') '..votes + } + end +end + +local function _options(player,root_frame) + local options = {'Please Select An option'} + local uuid = root_frame.name + local poll = global.active[uuid] + if not poll then return {'Invalid Poll'} end + for _,answer in pairs(poll.answers) do + table.insert(options,answer) + end + return options +end + +local option_drop_down = Gui.inputs.add_drop_down('option-drop-down-polls',_options,1,function(player,selected,items,element) + local uuid = element.parent.name + local poll = global.active[uuid] + if not poll then return end + if poll.voted[player.index] and poll.voted[player.index] > 1 then + local old_vote = poll.voted[player.index] + poll.votes[old_vote-1] = poll.votes[old_vote-1] and poll.votes[old_vote-1]-1 or 0 + end + if element.selected_index > 1 then + poll.votes[element.selected_index-1] = poll.votes[element.selected_index-1] and poll.votes[element.selected_index-1]+1 or 1 + end + poll.voted[player.index]=element.selected_index + element.parent.answer.caption = 'Your Answer: '..selected +end) + +local prev = Gui.inputs{ + type='button', + name='prev-poll', + caption='utility/hint_arrow_left' +}:on_event('click',function(event) + local parent = event.element.parent + local index = parent.parent.current_index.caption + local _index = tonumber(index)-1 + if _index < 1 then _index = #global.old end + parent.parent.current_index.caption = _index + parent.parent.title.title.caption = 'Viewing Poll: '.._index + draw_poll(parent.parent.poll_area) +end) + +local next = Gui.inputs{ + type='button', + name='next-poll', + caption='utility/hint_arrow_right' +}:on_event('click',function(event) + local parent = event.element.parent + local index = parent.parent.current_index.caption + local _index = tonumber(index)+1 + if _index > #global.old then _index = 1 end + parent.parent.current_index.caption = _index + parent.parent.title.title.caption = 'Viewing Poll: '.._index + draw_poll(parent.parent.poll_area) +end) + +local poll_question_input = Gui.inputs.add_text('poll-question-input',true,'Question',function(player,text,element) + local options = element.parent.options + if not options.question then options.add{type='label',name='question',caption=''} + else options.question.caption = text end +end) + +local _self_reference_poll_option_input = nil +local poll_option_input = Gui.inputs.add_text('poll-option-input',true,'Enter Option',function(player,text,element) + local options = element.parent.parent.parent.options + if not options[element.parent.name] then options.add{type='label',name=element.parent.name,caption=text} + else options[element.parent.name].caption = text end + if options.last.caption == element.parent.name then + options.last.caption = tonumber(options.last.caption)+1 + _self_reference_poll_option_input(element.parent.parent.add{type='flow',name=options.last.caption}).style.minimal_width = 200 + end +end) +_self_reference_poll_option_input = poll_option_input + +local function poll_assembler(frame) + frame.clear() + local options = frame.add{type='flow',name='options'} + options.style.visible = false + options.add{type='label',name='last',caption='2'} + poll_question_input(frame).style.minimal_width = 200 + local flow = frame.add{type='flow',direction='vertical'} + poll_option_input(flow.add{type='flow',name='1'}).style.minimal_width = 200 + poll_option_input(flow.add{type='flow',name='2'}).style.minimal_width = 200 +end + +local create_poll = Gui.inputs{ + type='button', + name='create-poll', + caption='utility/add' +}:on_event('click',function(event) + local parent = event.element.parent + if event.element.sprite == 'utility/enter' then + local inputs = parent.parent.poll_area.options + if not inputs then + event.element.sprite = 'utility/add' + draw_poll(parent.parent.poll_area) + return + end + local options = {} + for _,option in pairs(inputs.children) do + if option.name ~= 'question' and option.name ~= 'last' then + if option.caption ~= 'Enter Option' and option.caption ~= '' then table.insert(options,option.caption) end + end + end + if not inputs.question or #options == 0 then + event.element.sprite = 'utility/add' + draw_poll(parent.parent.poll_area) + return + end + local uuid = _poll_data(inputs.question.caption,options) + Gui.popup.open('polls',{uuid=uuid}) + event.element.sprite = 'utility/add' + draw_poll(parent.parent.poll_area) + else + event.element.sprite = 'utility/enter' + poll_assembler(parent.parent.poll_area) + end +end) + +ThisModule.Gui = Gui.popup{ + name='polls', + caption={'ExpGamingPlayer-polls.name'}, + draw=function(self,frame,data) + frame.style.right_padding = 5 + frame.style.bottom_padding = 5 + local uuid = data.uuid + local poll = global.active[tostring(uuid)] + if not poll then return end + local flow = frame.add{ + type='flow', + name=tostring(uuid), + direction='vertical' + } + flow.add{type='label',caption={'ExpGamingPlayer-polls.time-left',poll_time_out}} + flow.add{type='label',caption='Question: '..poll.question} + flow.add{type='label',name='answer',caption='Your Answer: None'} + option_drop_down(flow) + end +}:add_left{ + caption='utility/item_editor_icon', + tooltip={'ExpGamingPlayer-polls.tooltip'}, + draw=function(self,frame) + frame.caption={'ExpGamingPlayer-polls.name'} + frame.add{ + type='label', + name='current_index', + caption=1 + }.style.visible = false + local title = frame.add{ + type='flow', + name='title' + } + local btn = prev:draw(title) + btn.style.width = 20 + btn.style.height = 20 + title.add{ + type='label', + name='title', + caption='Viewing Poll: 1', + style='caption_label' + } + btn = next:draw(title) + btn.style.width = 20 + btn.style.height = 20 + if Role and Role.allowed(frame.player_index,'create-poll') or game.players[frame.player_index].admin then + btn = create_poll:draw(title) + btn.style.width = 20 + btn.style.height = 20 + end + local flow = frame.add{ + type='flow', + name='poll_area', + direction='vertical' + } + draw_poll(flow) + end, + can_open=function(player) + if #global.old > 0 then return true + elseif Role and Role.allowed(player,'create-poll') or player.admin then return true + else return {'ExpGamingPlayer-polls.no-poll'} end + end +} +-- Event Handlers Define + +-- Module Return +-- when called it will toggle the left gui for this player +return setmetatable(ThisModule,{__call=function(self,...) self.Gui(...) end}) \ No newline at end of file diff --git a/modules/ExpGamingPlayer/polls/locale/de.cfg b/modules/ExpGamingPlayer/polls/locale/de.cfg new file mode 100644 index 00000000..b476a903 --- /dev/null +++ b/modules/ExpGamingPlayer/polls/locale/de.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Umfragen +tooltip=Alte Umfragen ansehen +no-poll=Keine alten Umfragen +end=Die Umfrage hat gerade geendet: __1__ +winner=__1__ hatte die meisten Stimmen. +time-left=Du hast noch __1__s um deine Wahl zu erfassen. \ No newline at end of file diff --git a/modules/ExpGamingPlayer/polls/locale/en.cfg b/modules/ExpGamingPlayer/polls/locale/en.cfg new file mode 100644 index 00000000..afd15bf3 --- /dev/null +++ b/modules/ExpGamingPlayer/polls/locale/en.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Polls +tooltip=View Old Polls +no-poll=No Old Polls +end=Poll Just Ended: __1__ +winner=__1__ had the most votes. +time-left=You will have __1__s to pick. \ No newline at end of file diff --git a/modules/ExpGamingPlayer/polls/locale/fr.cfg b/modules/ExpGamingPlayer/polls/locale/fr.cfg new file mode 100644 index 00000000..afd15bf3 --- /dev/null +++ b/modules/ExpGamingPlayer/polls/locale/fr.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Polls +tooltip=View Old Polls +no-poll=No Old Polls +end=Poll Just Ended: __1__ +winner=__1__ had the most votes. +time-left=You will have __1__s to pick. \ No newline at end of file diff --git a/modules/ExpGamingPlayer/polls/locale/nl.cfg b/modules/ExpGamingPlayer/polls/locale/nl.cfg new file mode 100644 index 00000000..928ddefb --- /dev/null +++ b/modules/ExpGamingPlayer/polls/locale/nl.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Polls +tooltip=Laat oude polls zien +no-poll=Geen oude polls +end=Poll is zojuist beëindigd: __1__ +winner=__1__ had de meeste stemmen. +time-left=Je hebt __1__s om te kiezen. diff --git a/modules/ExpGamingPlayer/polls/locale/sv-SE.cfg b/modules/ExpGamingPlayer/polls/locale/sv-SE.cfg new file mode 100644 index 00000000..e9050a52 --- /dev/null +++ b/modules/ExpGamingPlayer/polls/locale/sv-SE.cfg @@ -0,0 +1,7 @@ +[ExpGamingPlayer-polls] +name=Undersökningar +tooltip=Se gamla undersökningar +no-poll=Inga gamla undersökningar +end=Röstning slutade nyss: __1__ +winner=__1__ hade flest röster. +time-left=Du kommer att få __1__s på dig att välja. \ No newline at end of file diff --git a/modules/ExpGamingPlayer/polls/softmod.json b/modules/ExpGamingPlayer/polls/softmod.json new file mode 100644 index 00000000..d5c416b6 --- /dev/null +++ b/modules/ExpGamingPlayer/polls/softmod.json @@ -0,0 +1,19 @@ +{ + "name": "ExpGamingPlayer.polls", + "version": "4.0.0", + "description": "Adds a poll gui into the game for quick polls (default 90 seconds)", + "location": "FSM_ARCHIVE", + "keywords": [ + "Polls", + "Poll", + "Question", + "Gui" + ], + "dependencies": { + "ExpGamingCore.Gui": "^4.0.0", + "ExpGamingCore.Server": "^4.0.0", + "ExpGamingCore.Role": "?^4.0.0" + }, + "collection": "ExpGamingPlayer@4.0.0", + "submodules": {} +} diff --git a/modules/ExpGamingPlayer/softmod.json b/modules/ExpGamingPlayer/softmod.json new file mode 100644 index 00000000..e31dddb6 --- /dev/null +++ b/modules/ExpGamingPlayer/softmod.json @@ -0,0 +1,23 @@ +{ + "name": "ExpGamingPlayer", + "version": "4.0.0", + "description": "Useful collection of modules for displaying player infomation.", + "location": "FSM_ARCHIVE", + "keywords": [ + "ExpGaming", + "Player", + "Information", + "AFK" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "submodules": { + "ExpGamingPlayer.afkKick": "4.0.0", + "ExpGamingPlayer.playerInfo": "4.0.0", + "ExpGamingPlayer.playerList": "4.0.0", + "ExpGamingPlayer.inventorySearch": "4.0.0", + "ExpGamingPlayer.polls": "4.0.0" + }, + "dependencies": {} +} diff --git a/modules/FactorioStdLib/Color/control.lua b/modules/FactorioStdLib/Color/control.lua new file mode 100644 index 00000000..9ccedbc5 --- /dev/null +++ b/modules/FactorioStdLib/Color/control.lua @@ -0,0 +1,232 @@ +--- A defines module for retrieving colors by name. +-- Extends the Factorio defines table. +-- @module StdLib.Color +-- @alias defines.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. +-- @table defines.color +-- @field white {r=1.00,g=1.00,b=1.00} +-- @field black {r=0.00,g=0.00,b=0.00} +-- @field darkgrey {r=0.25,g=0.25,b=0.25} +-- @field grey {r=0.50,g=0.50,b=0.50} +-- @field lightgrey {r=0.75,g=0.75,b=0.75} +-- @field red {r=1.00,g=0.00,b=0.00} +-- @field darkred {r=0.50,g=0.00,b=0.00} +-- @field lightred {r=1.00,g=0.50,b=0.50} +-- @field green {r=0.00,g=1.00,b=0.00} +-- @field darkgreen {r=0.00,g=0.50,b=0.00} +-- @field lightgreen {r=0.50,g=1.00,b=0.50} +-- @field blue {r=0.00,g=0.00,b=1.00} +-- @field darkblue {r=0.00,g=0.00,b=0.50} +-- @field lightblue {r=0.50,g=0.50,b=1.00} +-- @field orange {r=1.00,g=0.55,b=0.10} +-- @field yellow {r=1.00,g=1.00,b=0.00} +-- @field pink {r=1.00,g=0.00,b=1.00} +-- @field purple {r=0.60,g=0.10,b=0.60} +-- @field brown {r=0.60,g=0.40,b=0.10} +defines.color = { + 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} +} +local colors = defines.color + +--- Returns white for dark colors or black for lighter colors. +-- @table defines.anticolor +defines.anticolor = { + green = colors.black, -- defines.color.black + grey = colors.black, -- defines.color.black + lightblue = colors.black, -- defines.color.black + lightgreen = colors.black, -- defines.color.black + lightgrey = colors.black, -- defines.color.black + lightred = colors.black, -- defines.color.black + orange = colors.black, -- defines.color.black + white = colors.black, -- defines.color.black + yellow = colors.black, -- defines.color.black + black = colors.white, -- defines.color.white + blue = colors.white, -- defines.color.white + brown = colors.white, -- defines.color.white + darkblue = colors.white, -- defines.color.white + darkgreen = colors.white, -- defines.color.white + darkgrey = colors.white, -- defines.color.white + darkred = colors.white, -- defines.color.white + pink = colors.white, -- defines.color.white + purple = colors.white, -- defines.color.white + red = colors.white -- defines.color.white +} + +--- Returns a lighter color of a named color +-- @table defines.lightcolor +defines.lightcolor = { + white = colors.lightgrey, -- defines.color.lightgrey + grey = colors.darkgrey, -- defines.color.darkgrey + lightgrey = colors.grey, -- defines.color.grey + red = colors.lightred, -- defines.color.lightred + green = colors.lightgreen, -- defines.color.lightgreen + blue = colors.lightblue, -- defines.color.lightblue + yellow = colors.orange, -- defines.color.orange + pink = colors.purple -- defines.color.purple +} + +-- added by cooldude260 + +--- Returns a lighter color of a named color. +-- @table defines.textcolor +-- @field info {r=0.21,g=0.95,b=1.00} +-- @field bg {r=0.00,g=0.00,b=0.00} +-- @field low {r=0.18,g=0.77,b=0.18} +-- @field med {r=1.00,g=0.89,b=0.26} +-- @field high {r=1.00,g=0.33,b=0.00} +-- @field crit {r=1.00,g=0.00,b=0.00} +defines.textcolor = { + 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} +} + +-- metatable remade by cooldude +local _mt = { + __index=function(tbl,key) + return rawget(tbl,tostring(key):lower()) or rawget(defines.color,'white') + end, + __pairs=function(tbl) + return function() + local v + k, v = next(tbl, k) + return k, (v and {r = v['r'], g = v['g'], b = v['b'], a = v['a']}) or nil + end, tbl, nil + end, + __eq=function(tbl1,tbl2) + return tbl1.r == tbl2.r and tbl1.g == tbl2.g and tbl1.b == tbl2.b and tbl1.a == tbl2.a + end +} + +setmetatable(defines.color, _mt) +setmetatable(defines.anticolor, _mt) +setmetatable(defines.textcolor, _mt) +setmetatable(defines.lightcolor, _mt) + +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. +--
    +--
  • If ***alpha*** is given, set `color.a` to it. +--
  • If ***alpha*** is not given, and if the given color table does not have a value for `color.a`, set `color.a` to 1. +--
  • If ***alpha*** is not given, and if the given color table already has a value for `color.a`, then leave `color.a` alone. +--
+-- @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 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 table c_arr the color to convert +-- @treturn 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 a color table with RGB converted from Hex and with alpha +function Color.from_hex(hex, alpha) + if not _G.Game then error('StdLib/Game not loaded') end + _G.Game.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 diff --git a/modules/FactorioStdLib/Color/softmod.json b/modules/FactorioStdLib/Color/softmod.json new file mode 100644 index 00000000..c95f14bc --- /dev/null +++ b/modules/FactorioStdLib/Color/softmod.json @@ -0,0 +1,16 @@ +{ + "name": "FactorioStdLib.Color", + "version": "0.8.0", + "description": "A defines module for retrieving colors by name.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Standard Library", + "Lib", + "StdLib", + "Color", + "Extends" + ], + "dependencies": {}, + "collection": "FactorioStdLib@0.8.0", + "submodules": {} +} diff --git a/StdLib/game.lua b/modules/FactorioStdLib/Game/control.lua similarity index 96% rename from StdLib/game.lua rename to modules/FactorioStdLib/Game/control.lua index e108610e..b7608965 100644 --- a/StdLib/game.lua +++ b/modules/FactorioStdLib/Game/control.lua @@ -1,14 +1,13 @@ --- The game module. --- @module Game --- @usage local Game = require('stdlib/game') +-- @module StdLib.Game local Game = { --luacheck: allow defined top VALID_FILTER = function(v) return v and v.valid end, - _protect = function(module_name) + _protect = function(moduleName) return { - __newindex = function() error("Attempt to mutatate read-only "..module_name.." Module") end, + __newindex = function() error("Attempt to mutatate read-only "..moduleName.." Module") end, __metatable = true } end, diff --git a/modules/FactorioStdLib/Game/softmod.json b/modules/FactorioStdLib/Game/softmod.json new file mode 100644 index 00000000..76b50163 --- /dev/null +++ b/modules/FactorioStdLib/Game/softmod.json @@ -0,0 +1,16 @@ +{ + "name": "FactorioStdLib.Game", + "version": "0.8.0", + "description": "The game module.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Standard Library", + "Lib", + "StdLib", + "Game", + "Extends" + ], + "dependencies": {}, + "collection": "FactorioStdLib@0.8.0", + "submodules": {} +} diff --git a/StdLib/string.lua b/modules/FactorioStdLib/String/control.lua similarity index 98% rename from StdLib/string.lua rename to modules/FactorioStdLib/String/control.lua index b151e34a..24ff26ad 100644 --- a/StdLib/string.lua +++ b/modules/FactorioStdLib/String/control.lua @@ -1,6 +1,6 @@ --- Extends Lua 5.2 string. --- @module string --- @see string +-- @module StdLib.String +-- @alias string -- luacheck: globals string (Allow mutating string) diff --git a/modules/FactorioStdLib/String/softmod.json b/modules/FactorioStdLib/String/softmod.json new file mode 100644 index 00000000..3ef2d9a6 --- /dev/null +++ b/modules/FactorioStdLib/String/softmod.json @@ -0,0 +1,16 @@ +{ + "name": "FactorioStdLib.String", + "version": "0.8.0", + "description": "Extends Lua 5.2 string.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Standard Library", + "Lib", + "StdLib", + "String", + "Extends" + ], + "dependencies": {}, + "collection": "FactorioStdLib@0.8.0", + "submodules": {} +} diff --git a/StdLib/table.lua b/modules/FactorioStdLib/Table/control.lua similarity index 71% rename from StdLib/table.lua rename to modules/FactorioStdLib/Table/control.lua index 4087ef83..96e063ca 100644 --- a/StdLib/table.lua +++ b/modules/FactorioStdLib/Table/control.lua @@ -1,6 +1,6 @@ --- Extends Lua 5.2 table. --- @module table --- @see table +-- @module StdLib.Table +-- @alias table -- luacheck: globals table (Allow mutating global table) @@ -66,14 +66,40 @@ function table.find(tbl, func, ...) return nil end +--- Finds the first index at which the value appears in the table +-- @usage table.index({'foo','bar','baz'},'bar') -- retuns 2,'bar' +-- @tparam table tbl the table to search though +-- @param value the value you want the index of +-- @treturn number the index that the value apeears at +-- @return the value in that possition +function table.index(tbl, value) + for k, v in pairs(tbl) do + if v == value then + return k, v + end + end + return nil +end + +--- Returns a boolean on weather the table includes the value or not +-- @usage table.includes({'foo','bar','baz'},'bar') -- retuns true +-- @tparam table tbl the table to search though +-- @param value the value you want the index of +-- @treturn boolean if the table includes the value +function table.includes(tbl, value) + for k, v in pairs(tbl) do + if v == value then + return true + end + end + return false +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 +-- @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 @@ -246,28 +272,6 @@ function table.deepcopy(object) return _copy(object) end ---- Default table comparator sort function. --- @local --- @param x one comparator operand --- @param y the other comparator operand --- @return true if x logically comes before y in a list, false otherwise -local sortfunc = - function(x, y) --sorts tables with mixed index types. - local tx = type(x) - local ty = type(y) - if tx == ty then - if type(x) == 'string' then - return string.lower(x) < string.lower(y) - else - return x < y - end - elseif tx == 'number' then - return true --only x is a number and goes first - else - return false --only y is a number and goes first - end - 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() @@ -289,7 +293,19 @@ function table.values(tbl, sorted, as_string) end end if sorted then - table.sort(valueset, sortfunc) + 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 @@ -315,7 +331,19 @@ function table.keys(tbl, sorted, as_string) end end if sorted then - table.sort(keyset, sortfunc) + 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 @@ -395,128 +423,4 @@ function table.arr_to_bool(tbl) 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 - ---- Returns the list is a sorted way that would be expected by people (this is by key) --- @usage tbl = table.alphanumsort(tbl) --- @tparam tbl table the table to be sorted --- @treturn table the sorted table -function table.alphanumsort(tbl) - local o = table.keys(tbl) - local function padnum(d) local dec, n = string.match(d, "(%.?)0*(.+)") - return #dec > 0 and ("%.12f"):format(d) or ("%s%03d%s"):format(dec, #n, n) end - table.sort(o, function(a,b) - return tostring(a):gsub("%.?%d+",padnum)..("%3d"):format(#b) - < tostring(b):gsub("%.?%d+",padnum)..("%3d"):format(#a) end) - local _tbl = {} - for _,k in pairs(o) do _tbl[k] = tbl[k] end - return _tbl -end - ---- Returns the list is a sorted way that would be expected by people (this is by key) (faster alterative than above) --- @usage tbl = table.alphanumsort(tbl) --- @tparam tbl table the table to be sorted --- @treturn table the sorted table -function table.keysort(tbl) - local o = table.keys(tbl,true) - local _tbl = {} - for _,k in pairs(o) do _tbl[k] = tbl[k] end - return _tbl -end +end \ No newline at end of file diff --git a/modules/FactorioStdLib/Table/softmod.json b/modules/FactorioStdLib/Table/softmod.json new file mode 100644 index 00000000..e915763c --- /dev/null +++ b/modules/FactorioStdLib/Table/softmod.json @@ -0,0 +1,16 @@ +{ + "name": "FactorioStdLib.Table", + "version": "0.8.0", + "description": "Extends Lua 5.2 table.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Standard Library", + "Lib", + "StdLib", + "Table", + "Extends" + ], + "dependencies": {}, + "collection": "FactorioStdLib@0.8.0", + "submodules": {} +} diff --git a/modules/FactorioStdLib/softmod.json b/modules/FactorioStdLib/softmod.json new file mode 100644 index 00000000..7cc751b9 --- /dev/null +++ b/modules/FactorioStdLib/softmod.json @@ -0,0 +1,21 @@ +{ + "name": "FactorioStdLib", + "version": "0.8.0", + "description": "Factorio Standard Library Projects", + "location": "FSM_ARCHIVE", + "keywords": [ + "Standard Library", + "Lib", + "StdLib" + ], + "author": "Afforess", + "contact": "https://github.com/Afforess/Factorio-Stdlib/issues", + "license": "https://github.com/Afforess/Factorio-Stdlib/blob/master/LICENSE", + "submodules": { + "FactorioStdLib.Color": "0.8.0", + "FactorioStdLib.Game": "0.8.0", + "FactorioStdLib.String": "0.8.0", + "FactorioStdLib.Table": "0.8.0" + }, + "dependencies": {} +} diff --git a/modules/GameSettingsGui/control.lua b/modules/GameSettingsGui/control.lua new file mode 100644 index 00000000..2a447482 --- /dev/null +++ b/modules/GameSettingsGui/control.lua @@ -0,0 +1,193 @@ +--- A gui for controlling game settings with sliders as well as some global commands. +-- @module GameSettingsGui@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +-- Module Require +local Server = require('ExpGamingCore.Server') +local Gui = require('ExpGamingCore.Gui') + +-- Local Variables +--{type='slider',object='',key='',name='',min=x,max=y} +--{type='function',object='',key='',name='',param={}} +local basic_settings = { + {type='slider',object='force',key='manual_mining_speed_modifier',name='mining-speed',min=0,max=10}, + {type='slider',object='force',key='manual_crafting_speed_modifier',name='craft-speed',min=0,max=10}, + {type='slider',object='force',key='character_running_speed_modifier',name='running-speed',min=0,max=10}, + {type='slider',object='force',key='character_build_distance_bonus',name='build-distance',min=0,max=50}, + {type='slider',object='force',key='character_reach_distance_bonus',name='reach-distance',min=0,max=50}, + {type='slider',object='force',key='worker_robots_speed_modifier',name='bot-speed',min=0,max=10}, + {type='slider',object='force',key='laboratory_speed_modifier',name='lab-speed',min=0,max=10}, + {type='slider',object='force',key='stack_inserter_capacity_bonus',name='stack-bonus',min=1,max=30} +} + +local advanced_settings = { + {type='slider',object='force',key='quickbar_count',name='quickbar-count',min=1,max=5}, + {type='slider',object='force',key='character_inventory_slots_bonus',name='inventory-size',min=0,max=1000}, + {type='slider',object='force',key='mining_drill_productivity_bonus',name='mining-prod',min=0,max=10}, + {type='slider',object='game',key='speed',name='game-speed',min=0.01,max=5}, + {type='function',object='surface',key='clear_pollution',name='clear-pollution'}, + {type='function',object='game',key='server_save',name='save'}, + {type='function',object='force',key='reset_technology_effects',name='reload-effects'}, + {type='function',object='enemy',key='kill_all_units',name='kill-biters'}, + {type='function',object='force',key='rechart',name='reload-map'}, + {type='function',object='game',key='force_crc',name='crc'}, + {type='function',object='force',key='reset',name='reset-force'} +} + +local personal_settings = { + {type='slider',object='player',key='character_mining_speed_modifier',name='mining-speed',min=0,max=10}, + {type='slider',object='player',key='character_crafting_speed_modifier',name='craft-speed',min=0,max=10}, + {type='slider',object='player',key='character_running_speed_modifier',name='running-speed',min=0,max=10}, + {type='slider',object='player',key='character_build_distance_bonus',name='build-distance',min=0,max=50}, + {type='slider',object='player',key='character_reach_distance_bonus',name='reach-distance',min=0,max=50}, + {type='slider',object='player',key='character_inventory_slots_bonus',name='inventory-size',min=0,max=1000}, + {type='slider',object='player',key='quickbar_count_bonus',name='quickbar-count',min=0,max=5} +} + +local _root_list = {basic_settings=basic_settings,advanced_settings=advanced_settings,personal_settings=personal_settings} + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Function Define +local function _get_data(root_frame) + local object = root_frame.name + local key = root_frame.setting_name.caption + for _,setting in pairs(_root_list[object]) do + if key == setting.key then return setting end + end +end + +local function _object_list(player) return {game=game,player=player,force=player.force,enemy=game.forces['enemy'],surface=player.surface} end + +for name,group in pairs(_root_list) do + for key,setting in pairs(group) do + local _added = nil + if setting.type == 'slider' then + _added = Gui.inputs.add_slider('game-settings-'..setting.name,'horizontal',setting.min,setting.max, + function(player,root_frame) + local data = _get_data(root_frame) + local objects = _object_list(player) + local object = objects[data.object] + return object[data.key] or 1 + end, + function(player,value,percent,element) + local data = _get_data(element.parent) + local objects = _object_list(player) + local object = objects[data.object] + local _caption = string.format('%.2f',value); if value > 2 then _caption = string.format('%.2f',math.floor(value)) end + object[data.key] = tonumber(_caption) + element.parent.counter.caption = _caption + end + ) + elseif setting.type == 'function' then + _added = Gui.inputs.add_checkbox('game-settings-'..setting.name,true,nil,false,function(player,element) + local data = _get_data(element.parent.parent) + local objects = _object_list(player) + local object = objects[data.object] + -- if key is a function it will run the function rather than attempt to get a function + if is_type(data.key,'function') then pcall(data.key,object,unpack(data.params)) + else pcall(object[data.key],unpack(data.params)) end + Server.new_thread{ + timeout=60, + data=element + }:on_event('timeout',function(self) + if self.data and self.data.valid then + self.data.parent.parent['game-settings-are-you-sure'].state = false + self.data.parent.style.visible = false + self.data.state = false + end + end):open() + end) + if not setting.params then setting.params = {} end + end + setting._loaded = _added + setting._group = name + end +end + +local are_you_sure = Gui.inputs.add_checkbox('game-settings-are-you-sure',true,nil,false,function(player,element) + element.parent.sure.style.visible = true + Server.new_thread{ + timeout=600, + data=element + }:on_event('timeout',function(self) + if self.data and self.data.valid then + self.data.state = false + self.data.parent.sure.style.visible = false + end + end):open() +end) + +local function _draw_setting(frame,setting) + frame = frame.add{type='flow'}.add{ + type='flow', + name=setting._group + } + frame.add{ + type='label', + caption={'GameSettingsGui.effect-'..setting.name}, + style='caption_label' + } + frame.add{ + type='label', + caption=setting.key, + name='setting_name' + }.style.visible = false + if setting.type == 'slider' then + local slider = setting._loaded(frame) + slider.style.width = 300 + local _caption = string.format('%.2f',slider.slider_value); if slider.slider_value > 2 then _caption = tostring(math.floor(slider.slider_value)) end + frame.add{ + type='label', + name='counter', + caption=_caption + } + elseif setting.type == 'function' then + are_you_sure(frame) + local flow = frame.add{type='flow',name='sure'} + flow.style.visible = false + flow.add{ + type='label', + caption={'GameSettingsGui.sure'}, + style='bold_red_label' + } + setting._loaded(flow) + end +end + +ThisModule.Gui = Gui.center{ + name='game-settings', + caption='utility/no_building_material_icon', + tooltip={'GameSettingsGui.tooltip'} +}:add_tab('basic',{'GameSettingsGui.basic-name'},{'GameSettingsGui.basic-name'},function(frame) + frame.add{ + type='label', + caption={'GameSettingsGui.basic-message'} + }.style.single_line = false + for _,setting in pairs(basic_settings) do + _draw_setting(frame,setting) + end +end):add_tab('advanced',{'GameSettingsGui.advanced-name'},{'GameSettingsGui.advanced-tooltip'},function(frame) + frame.add{ + type='label', + caption={'GameSettingsGui.advanced-message'} + }.style.single_line = false + for _,setting in pairs(advanced_settings) do + _draw_setting(frame,setting) + end +end):add_tab('personal',{'GameSettingsGui.personal-name'},{'GameSettingsGui.personal-tooltip'},function(frame) + frame.add{ + type='label', + caption={'GameSettingsGui.personal-message'} + }.style.single_line = false + for _,setting in pairs(personal_settings) do + _draw_setting(frame,setting) + end +end) + +-- Module return +-- when called it will open the center gui for the player +return setmetatable(ThisModule,{__call=function(self,...) self.Gui(...) end}) \ No newline at end of file diff --git a/modules/GameSettingsGui/locale/de.cfg b/modules/GameSettingsGui/locale/de.cfg new file mode 100644 index 00000000..dece78e7 --- /dev/null +++ b/modules/GameSettingsGui/locale/de.cfg @@ -0,0 +1,31 @@ +[GameSettingsGui] +name=Spieleinstellungen +tooltip=Erlaubt das Modifizieren von Spieleinstellungen. Bitte mit Bedacht benutzen. +basic-name=Einfache Einstellungen +basic-tooltip=Diese Einstellungen sind ohne Probleme veränderbar, sie verursachen keine großen Probleme im nachhinein. +basic-message=Dies sind fraktionsweite Einstellungen, welche genutzt werden können um das Spiel zu vereinfachen und es für Alle angenehmer zu machen. +advanced-name=Erweiterte Einstellungen +advanced-tooltip=Diese Einstellungen sollten nicht von Leuten benutzt werden, die nicht wissen was sie tun. +advanced-message=Bitte ändere keine dieser Einstellungen ausser du bist dir 100% sicher was sie tun,lass game.speed allein, da es einen viel größeren Effekt hat als du denkst. +personal-name=Persönliche Einstellungen +personal-tooltip=Diese Einstellungen betreffen nur deinen Spieler. Wenn man dich beim cheaten erwischt bist du auf dich allein gestellt. +personal-message=Diese Einstellungen betreffen nur deinen Spieler, übertreib es nicht ansonsten besteht die Gefahr, dass dich normale Spieler (gierige Kleinkinder) dabei erwischen (und rumheulen). +sure=Bist du dir Sicher?! +effect-mining-speed=Abbaugeschwindigkeit +effect-craft-speed=Herstellgeschwindigkeit +effect-running-speed=Laufgeschwindigkeit +effect-build-distance=Baudistanz +effect-reach-distance=Armreichweite +effect-bot-speed=Robotergeschwindigkeit +effect-lab-speed=Laborgeschwindigkeit +effect-stack-bonus=Stapelnonuss +effect-quickbar-count=Anzahl Schnellleistenelemente +effect-inventory-size=Inventargröße +effect-mining-prod=Abbauproduktivität +effect-game-speed=Spielgeschwindigkeit +effect-save=Spiel speichern +effect-reload-effects=Effekte neu laden +effect-reload-map=Minimap neu laden +effect-kill-biters=Töte alle Beisser +effect-crc=Forciere CRC check +effect-reset-force=Fraktion zurücksetzen \ No newline at end of file diff --git a/modules/GameSettingsGui/locale/en.cfg b/modules/GameSettingsGui/locale/en.cfg new file mode 100644 index 00000000..54825990 --- /dev/null +++ b/modules/GameSettingsGui/locale/en.cfg @@ -0,0 +1,32 @@ +[GameSettingsGui] +name=Game Settings +tooltip=Edits Game Settings. Please use responsibly. +basic-name=Basic Settings +basic-tooltip=These settings are safe to edit and have no big impact. +basic-message=Basic Settings can be used to improve game play for players. +advanced-name=Advanced Settings +advanced-tooltip=These settings should be left alone unless you know what you are doing. +advanced-message=Please do not touch the Advanced Settings unless you are 100% sure what you are doing: changes made to these settings might have a bigger impact than you realise. +personal-name=Personal Settings +personal-tooltip=Personal Settings only affect you. +personal-message=Personal Settings only affect your character. If you are spotted as a result of these settings, you are on your own! +sure=Are you sure? +effect-mining-speed=Mining Speed +effect-craft-speed=Crafting Speed +effect-running-speed=Running Speed +effect-build-distance=Build Distance +effect-reach-distance=Reach Distance +effect-bot-speed=Bot Speed +effect-lab-speed=Lab Speed +effect-stack-bonus=Stack Bonus +effect-quickbar-count=Quickbar Count +effect-inventory-size=Inventory Size +effect-mining-prod=Mining Productivity +effect-game-speed=Game Speed +effect-save=Save Game +effect-reload-effects=Reload Effects +effect-reload-map=Reload Minimap +effect-kill-biters=Kill Biters +effect-crc=Force CRC Check +effect-reset-force=Reset Force +effect-clear-pollution=Clear Pollution \ No newline at end of file diff --git a/modules/GameSettingsGui/locale/fr.cfg b/modules/GameSettingsGui/locale/fr.cfg new file mode 100644 index 00000000..f13485d0 --- /dev/null +++ b/modules/GameSettingsGui/locale/fr.cfg @@ -0,0 +1,31 @@ +[GameSettingsGui] +name=Game Settings +tooltip=Allows for editing of the game settings, please use resposibliy. +basic-name=Basic Settings +basic-tooltip=These settings are safe to change with no large effects. +basic-message=These settings are force wide settings which can be used to inprove gameplay and make it more enjoyible for players. +advanced-name=Advanced Settings +advanced-tooltip=These settings should be left alone unless you know what you are doing. +advanced-message=Please do not touch these settings at all unless you know 100% what they do and the effect of using them, leave game.speed alone it has a bigger effect then you think. +personal-name=Personal Settings +personal-tooltip=These will only effect you, if you are spoted you are on your own. +personal-message=These settings will only effect your player any changes you make are to be resposible ones and dont over do it or you may be caught using them. +sure=Are You Sure! +effect-mining-speed=Mining Speed +effect-craft-speed=Crafting Speed +effect-running-speed=Running Speed +effect-build-distance=Build Distance +effect-reach-distance=Reach Distance +effect-bot-speed=Bot Speed +effect-lab-speed=Lab Speed +effect-stack-bonus=Stack Bonus +effect-quickbar-count=Quickbar Count +effect-inventory-size=Inventory Size +effect-mining-prod=Mining Productivity +effect-game-speed=Game Speed +effect-save=Save Game +effect-reload-effects=Reload Effects +effect-reload-map=Reload Minimap +effect-kill-biters=Kill Biters +effect-crc=Force CRC Check +effect-reset-force=Reset Force \ No newline at end of file diff --git a/modules/GameSettingsGui/locale/nl.cfg b/modules/GameSettingsGui/locale/nl.cfg new file mode 100644 index 00000000..19017a6b --- /dev/null +++ b/modules/GameSettingsGui/locale/nl.cfg @@ -0,0 +1,31 @@ +[GameSettingsGui] +name=Game instellingen +tooltip=Maakt het mogelijk om gameinstellingen te wijzigen. Gebruik het verantwoord! +basic-name=Basis instellingen +basic-tooltip=Deze instellingen kunnen veilig worden gewijzigd. +basic-message=Deze instellingen kunnen worden gebruikt om het spelervaring voor de spelers te verbeteren. +advanced-name=Geavanceerde instellingen +advanced-tooltip=Het is ten zeerste aangeraden om niet aan deze instellingen te zitten, tenzij je weet wat je doet. +advanced-message=Waarschuwing: Niet aan deze instellingen zitten tenzij je honderd procent zeker weet wat je aan het doen bent. Het wijzigen van deze instellingen kunnen een groter effect hebben dan je denkt. +personal-name=Persoonlijke instellingen +personal-tooltip=Deze instellingen hebben alleen effect op jouw speler. +personal-message=Deze instellingen hebben alleen effect op jouw speler: gebruik het verantwoord, aangezien het overmatig gebruik van deze instellingen niet zijn toegestaan. +sure=Weet je het zeker? +effect-mining-speed=Mining Snelheid +effect-craft-speed=Crafting Snelheid +effect-running-speed=Ren Snelheid +effect-build-distance=Bouwafstand +effect-reach-distance=Bereik +effect-bot-speed=Bot Snelheid +effect-lab-speed=Lab Snelheid +effect-stack-bonus=Stack Bonus +effect-quickbar-count=Quickbar Count +effect-inventory-size=Inventory grootte +effect-mining-prod=Mining Productiviteit +effect-game-speed=Gamesnelheid +effect-save=Opslaan +effect-reload-effects=Effecten herladen +effect-reload-map=Minimap herladen +effect-kill-biters=Biters vermoorden +effect-crc=Forceer CRC check +effect-reset-force=Forceren resetten diff --git a/modules/GameSettingsGui/locale/sv-SE.cfg b/modules/GameSettingsGui/locale/sv-SE.cfg new file mode 100644 index 00000000..88185c07 --- /dev/null +++ b/modules/GameSettingsGui/locale/sv-SE.cfg @@ -0,0 +1,31 @@ +[GameSettingsGui] +name=Game Settings +tooltip=Edits Game Settings. Please use responsibly. +basic-name=Basic Settings +basic-tooltip=These settings are safe to edit and have no big impact. +basic-message=Basic Settings can be used to improve game play for players. +advanced-name=Advanced Settings +advanced-tooltip=These settings should be left alone unless you know what you are doing. +advanced-message=Please do not touch the Advanced Settings unless you are 100% sure what you are doing: changes made to these settings might have a bigger impact than you realize. +personal-name=Personal Settings +personal-tooltip=Personal Settings only affects you. +personal-message=Personal Settings only affects your character. If you are spotted as a result of these settings, you are on your own! +sure=Are you sure? +effect-mining-speed=Mining Speed +effect-craft-speed=Crafting Speed +effect-running-speed=Running Speed +effect-build-distance=Build Distance +effect-reach-distance=Reach Distance +effect-bot-speed=Bot Speed +effect-lab-speed=Lab Speed +effect-stack-bonus=Stack Bonus +effect-quickbar-count=Quickbar Count +effect-inventory-size=Inventory Size +effect-mining-prod=Mining Productivity +effect-game-speed=Game Speed +effect-save=Save Game +effect-reload-effects=Reload Effects +effect-reload-map=Reload Minimap +effect-kill-biters=Kill Biters +effect-crc=Force CRC Check +effect-reset-force=Reset Force diff --git a/modules/GameSettingsGui/softmod.json b/modules/GameSettingsGui/softmod.json new file mode 100644 index 00000000..2e09943f --- /dev/null +++ b/modules/GameSettingsGui/softmod.json @@ -0,0 +1,21 @@ +{ + "name": "GameSettingsGui", + "version": "4.0.0", + "description": "A gui for controlling game settings with sliders as well as some global commands.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Gui", + "Game", + "Game Settings", + "Settings", + "Admin" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "ExpGamingCore.Server": "^4.0.0", + "ExpGamingCore.Gui": "^4.0.0" + }, + "submodules": {} +} diff --git a/modules/GuiAnnouncements/control.lua b/modules/GuiAnnouncements/control.lua new file mode 100644 index 00000000..d1a434d2 --- /dev/null +++ b/modules/GuiAnnouncements/control.lua @@ -0,0 +1,110 @@ +--- Creates a gui for making and receiving announcements +-- @module GuiAnnouncements@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- maybe make this not require Role and have it optional + +-- Module Require +local Game = require('FactorioStdLib.Game') +local Gui = require('ExpGamingCore.Gui') +local Role = require('ExpGamingCore.Role') + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Function Define +local function _roles(player) + local roles = {'Select Role'} + local _role = Role.get_highest(player) + for index,role_name in pairs(Role.order) do + if index >= _role.index then + table.insert(roles,role_name) + end + end + return roles +end + +local role_drop_down = Gui.inputs.add_drop_down('rank-drop-down-announcements',_roles,1,function(player,selected,items,element) + element.parent.role.caption = selected + if selected == 'Select Role' then element.parent['send-announcement'].style.visible = false + else element.parent['send-announcement'].style.visible = true end +end) + +local send_popup = Gui.inputs{ + type='button', + name='send-announcement', + caption='utility/export_slot' +}:on_event('click',function(event) + local player = Game.get_player(event) + local role = Role.get_highest(player) + local _role = Role.get(event.element.parent.role.caption); if not _role then return end + local sent_by = {'GuiAnnouncements.sent-by',player.name,role.name} + local role_name = _role.name..'s'; if role_name == Role.meta.default.name..'s' then role_name = 'Everyone' end + local sent_to = {'GuiAnnouncements.sent-to',role_name} + local message = event.element.parent.parent.message.text + local players = _role:get_players(true) + if _role.index == Role.meta.default.index then players = game.connected_players end + Gui.popup.open('announcements',{sent_by=sent_by,sent_to=sent_to,message=message},players) + player_return('Announcement sent to '..#players..' players ('..role_name..')',defines.textcolor.info,player) + verbose('Announcement sent to '..#players..' players ('..role_name..') by '..player.name..'('..role.name..') with message: '..message) + event.element.parent.parent.message.text = '' + Gui.left.close('announcements',player) +end) + +ThisModule.Gui = Gui.popup{ + name='announcements', + caption={'GuiAnnouncements.name'}, + draw=function(self,frame,data) + frame.style.right_padding = 5 + frame.style.bottom_padding = 5 + frame.add{type='label',caption=data.sent_by,style='caption_label'} + frame.add{type='label',caption=data.sent_to,style='caption_label'} + local text_box = frame.add{type='text-box'} + text_box.text = data.message + text_box.style.width = 400 + text_box.read_only = true + text_box.word_wrap = true + text_box.selectable = true + end +}:add_left{ + caption='item/programmable-speaker', + tooltip={'GuiAnnouncements.tooltip'}, + draw=function(self,frame) + frame.caption = {'GuiAnnouncements.name'} + frame = frame.add{ + type='flow', + direction='vertical' + } + local text_box = frame.add{ + type='text-box', + name='message' + } + text_box.style.width = 400 + text_box.style.minimal_height = 100 + text_box.read_only = false + text_box.word_wrap = true + text_box.selectable = true + local flow = frame.add{type='flow'} + flow.add{ + type='label', + caption={'GuiAnnouncements.select-rank'} + } + role_drop_down(flow) + local btn = send_popup(flow) + btn.style.visible = false + btn.style.height = 25 + btn.style.width = 25 + flow.add{ + type='label', + name='role', + caption='' + }.style.visible = false + end +} + +-- Module return +-- when called it will open the center gui for the player +return setmetatable(ThisModule,{__call=function(self,...) self.Gui(...) end}) \ No newline at end of file diff --git a/modules/GuiAnnouncements/locale/de.cfg b/modules/GuiAnnouncements/locale/de.cfg new file mode 100644 index 00000000..9744da36 --- /dev/null +++ b/modules/GuiAnnouncements/locale/de.cfg @@ -0,0 +1,6 @@ +[GuiAnnouncements] +name=Ankündigung +tooltip=Eine Ankündigung an Spieler senden +sent-to=Dies wurde zu __1__ gesendet +sent-by=Dies wurde von __1__ mit Rang __2__ gesendet +select-rank=Diese Nachricht wird gesendet an: \ No newline at end of file diff --git a/modules/GuiAnnouncements/locale/en.cfg b/modules/GuiAnnouncements/locale/en.cfg new file mode 100644 index 00000000..be1e94da --- /dev/null +++ b/modules/GuiAnnouncements/locale/en.cfg @@ -0,0 +1,6 @@ +[GuiAnnouncements] +name=Announcements +tooltip=Sends an announcement to all players +sent-to=This announcement is sent to __1__ +sent-by=This announcement was sent by __1__ ( __2__ ) +select-rank=This announcement will be sent to: \ No newline at end of file diff --git a/modules/GuiAnnouncements/locale/fr.cfg b/modules/GuiAnnouncements/locale/fr.cfg new file mode 100644 index 00000000..11041b57 --- /dev/null +++ b/modules/GuiAnnouncements/locale/fr.cfg @@ -0,0 +1,6 @@ +[GuiAnnouncements] +name=Announcement +tooltip=Sent an announcement to players +sent-to=This is sent to __1__ +sent-by=This was sent by __1__ of rank __2__ +select-rank=This message will be sent to: \ No newline at end of file diff --git a/modules/GuiAnnouncements/locale/nl.cfg b/modules/GuiAnnouncements/locale/nl.cfg new file mode 100644 index 00000000..5c92cc68 --- /dev/null +++ b/modules/GuiAnnouncements/locale/nl.cfg @@ -0,0 +1,6 @@ +[GuiAnnouncements] +name=Mededelingen +tooltip=Verstuurt een mededeling naar iedereen +sent-to=Deze mededeling is gestuurd naar __1__ +sent-by=Deze mededeling is gestuurd door __1__ ( __2__ ) +select-rank=Deze mededeling wordt gestuurd naar: diff --git a/modules/GuiAnnouncements/locale/sv-SE.cfg b/modules/GuiAnnouncements/locale/sv-SE.cfg new file mode 100644 index 00000000..2b3a8317 --- /dev/null +++ b/modules/GuiAnnouncements/locale/sv-SE.cfg @@ -0,0 +1,7 @@ + +[GuiAnnouncements] +name=Meddelanden +tooltip=Sänder ett meddelande till alla spelare +sent-to=Det här meddelandet är skickat till __1__ +sent-by=Det här meddelandet är skickat av __1__ ( __2__ ) +select-rank=Det här meddelandet kommer att skickas till: diff --git a/modules/GuiAnnouncements/softmod.json b/modules/GuiAnnouncements/softmod.json new file mode 100644 index 00000000..9867fd84 --- /dev/null +++ b/modules/GuiAnnouncements/softmod.json @@ -0,0 +1,20 @@ +{ + "name": "GuiAnnouncements", + "version": "4.0.0", + "description": "Creates a gui for making and reciving announcements", + "location": "FSM_ARCHIVE", + "keywords": [ + "Announcements", + "Gui", + "Admin" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Role": "^4.0.0", + "ExpGamingCore.Gui": "^4.0.0" + }, + "submodules": {} +} diff --git a/modules/PlayerAutoColor/control.lua b/modules/PlayerAutoColor/control.lua new file mode 100644 index 00000000..b4776c9e --- /dev/null +++ b/modules/PlayerAutoColor/control.lua @@ -0,0 +1,47 @@ +--- Assigns random colours to players (larger range than default) and allows predefined colours for users. +-- @module PlayerAutoColor@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Color = require('FactorioStdLib.Color') + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Global Define +local global = global{ + BADgamerNL={r=255,g=20,b=147}, + arty714={r=150,g=68,b=161}, + Cooldude2606={r=57,g=192,b=207}, + mark9064={r=99,g=0,b=255}, + eissturm={r=25,g=25,b=112}, + Sakama={r=20,g=213,b=80}, + Sakama={r=20,g=213,b=80}, + freek18={r=50,g=0,b=255}, + aldldl={r=0,g=131,b=255}, + NAD4X4={r=135,g=206,b=250}, + cydes={r=82,g=249,b=155}, + UUBlueFire={r=0,g=204,b=255} +} + +-- Event Handlers Define +script.on_event(defines.events.on_player_created, function(event) + local player = game.players[event.player_index] + local colours = table.keys(defines.color) + player.color = defines.color.black + while player.color.r == defines.color.black.r and player.color.g == defines.color.black.g and player.color.b == defines.color.black.b + or player.color.r == defines.color.white.r and player.color.g == defines.color.white.g and player.color.b == defines.color.white.b do + player.color = defines.color[colours[math.random(#colours)]] + if global[player.name] then + local c = global[player.name] + player.color = Color.from_rgb(c.r,c.g,c.b) + end + end + player.chat_color = player.color +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/PlayerAutoColor/softmod.json b/modules/PlayerAutoColor/softmod.json new file mode 100644 index 00000000..d028bba7 --- /dev/null +++ b/modules/PlayerAutoColor/softmod.json @@ -0,0 +1,19 @@ +{ + "name": "PlayerAutoColor", + "version": "4.0.0", + "description": "Assigns random colours to players (larger range than default) and allows predefined colours for users.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Colour", + "Color", + "Player", + "Vibrant" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "FactorioStdLib.Color": "^0.8.0" + }, + "submodules": {} +} diff --git a/modules/SpawnArea/control.lua b/modules/SpawnArea/control.lua new file mode 100644 index 00000000..d32258fd --- /dev/null +++ b/modules/SpawnArea/control.lua @@ -0,0 +1,126 @@ +--- Creates a safe spawn area with chests and auto refilling turrets. +-- @module SpawnArea@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Game = require('FactorioStdLib.Game') + +-- Local Variables +local turret_enabled = true +local turret_ammo = 'uranium-rounds-magazine' + +local tile_positions = require(module_path..'/src/spawn_tiles') +local entity_positions = require(module_path..'/src/spawn_entities') + +local global_offset = {x=0,y=-2} +local decon_radius = 20 +local decon_tile = 'concrete' +local pattern_radius = 50 +local pattern_tile = 'stone-path' + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Global Define +-- location of auto refill turrets +local global = global{ + {1,-3,-3}, + {1,-3,3}, + {1,3,-3}, + {1,3,3} +} + +-- Function Define +function ThisModule.afk_belt(surface,offset) + local belts = {{-0.5,-0.5,2},{0.5,-0.5,4},{-0.5,0.5,0},{0.5,0.5,6}} + for _,pos in pairs(belts) do + local position = {pos[1]+offset[1],pos[2]+offset[2]} + local belt = surface.create_entity{name='transport-belt',position=position,force='neutral',direction=pos[3]} + belt.destructible = false; belt.health = 0; belt.minable = false; belt.rotatable = false + end +end + +function ThisModule.auto_turret(surface,pos) + if not turret_enabled then error('Auto Turrets are disabled.') end + -- adds a new turret to the global list, returns index + local _return + if surface then + surface = Game.get_surface(surface) + if not surface then error('Surface is not valid.') end + local posx = pos.x or pos[1] or error('Position is not valid.') + local posy = pos.y or pos[2] or error('Position is not valid.') + _return = table.insert(global,{surface.index,posx,posy}) + end + -- spawns turrets and refills them + if not game.forces['spawn'] then game.create_force('spawn').set_cease_fire('player',true) game.forces['player'].set_cease_fire('spawn',true) end + for _,pos in pairs(global) do + surface = game.surfaces[pos[1]] + local turret = surface.find_entity('gun-turret',{pos[2],pos[3]}) + if not turret then + turret = surface.create_entity{name='gun-turret',position={pos[2],pos[3]},force='spawn'} + turret.destructible = false; turret.health = 0; turret.minable = false; turret.rotatable = false; turret.operable = false; turret.health = 0 + end + if turret.get_inventory(defines.inventory.turret_ammo).can_insert{name=turret_ammo,count=10} then + turret.get_inventory(defines.inventory.turret_ammo).insert{name=turret_ammo,count=10} + end + end +end + +-- Event Handlers Define +if turret_enabled then + script.on_event(defines.events.on_tick,function(event) + if event.tick % 3600 then + ThisModule.auto_turret() + end + end) +end + +script.on_event(defines.events.on_player_created, function(event) + if event.player_index == 1 then + local player = Game.get_player(event) + local surface = player.surface + local offset = {x=0,y=0} + local pattern_base_tile = surface.get_tile(player.position).name + if pattern_base_tile == 'deepwater' or pattern_base_tile == 'water' then pattern_base_tile = 'grass-1' end + local base_tiles = {} + local tiles = {} + -- generates a safe area of land and removes all entities + for x = -pattern_radius, pattern_radius do + for y = -pattern_radius, pattern_radius do + if x^2+y^2 < decon_radius^2 then + table.insert(base_tiles,{name=decon_tile,position={x+offset.x,y+offset.y}}) + local entities = surface.find_entities_filtered{area={{x+offset.x-1,y+offset.y-1},{x+offset.x,y+offset.y}}} + for _,entity in pairs(entities) do if entity.name ~= 'player' then entity.destroy() end end + elseif x^2+y^2 < pattern_radius^2 then + table.insert(base_tiles,{name=pattern_base_tile,position={x+offset.x,y+offset.y}}) + end + end + end + surface.set_tiles(base_tiles) + -- creates the pattern in the spawn + for _,position in pairs(tile_positions) do + table.insert(tiles,{name=pattern_tile,position={position[1]+offset.x+global_offset.x,position[2]+offset.y+global_offset.y}}) + end + surface.set_tiles(tiles) + -- spawns all the entities in spawn + for _,entity in pairs(entity_positions) do + entity = surface.create_entity{name=entity[1],position={entity[2]+offset.x+global_offset.x,entity[3]+offset.y+global_offset.y},force='neutral'} + entity.destructible = false; entity.health = 0; entity.minable = false; entity.rotatable = false + end + -- generates spawn turrets and afk belts + if turret_enabled then ThisModule.auto_turret() end + ThisModule.afk_belt(surface,{offset.x-5,offset.y-5}) + ThisModule.afk_belt(surface,{offset.x+5,offset.y-5}) + ThisModule.afk_belt(surface,{offset.x-5,offset.y+5}) + ThisModule.afk_belt(surface,{offset.x+5,offset.y+5}) + -- sets the spawn and moves the first player there + player.force.set_spawn_position(offset,surface) + player.teleport(offset,surface) + end +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/SpawnArea/softmod.json b/modules/SpawnArea/softmod.json new file mode 100644 index 00000000..240e1af4 --- /dev/null +++ b/modules/SpawnArea/softmod.json @@ -0,0 +1,19 @@ +{ + "name": "SpawnArea", + "version": "4.0.0", + "description": "Creates a safe spawn area with chests and auto refilling turrets.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Spawn", + "Safe", + "Turrets", + "Auto Refill" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "FactorioStdLib.Game": "^0.8.0" + }, + "submodules": {} +} diff --git a/modules/SpawnArea/src/spawn_entities.lua b/modules/SpawnArea/src/spawn_entities.lua new file mode 100644 index 00000000..408082d5 --- /dev/null +++ b/modules/SpawnArea/src/spawn_entities.lua @@ -0,0 +1,16 @@ +return { + {"stone-wall",-10,-6},{"stone-wall",-10,-5},{"stone-wall",-10,-4},{"stone-wall",-10,-3},{"stone-wall",-10,-2},{"stone-wall",-10,-1},{"stone-wall",-10,0},{"stone-wall",-10,3},{"stone-wall",-10,4},{"stone-wall",-10,5}, + {"stone-wall",-10,6},{"stone-wall",-10,7},{"stone-wall",-10,8},{"stone-wall",-10,9},{"stone-wall",-8,-8},{"small-lamp",-8,-4},{"small-lamp",-8,-1},{"iron-chest",-8,0},{"iron-chest",-8,3},{"small-lamp",-8,4}, + {"small-lamp",-8,7},{"stone-wall",-8,11},{"stone-wall",-7,-8},{"small-electric-pole",-7,-2},{"iron-chest",-7,0},{"iron-chest",-7,3},{"small-electric-pole",-7,5},{"stone-wall",-7,11},{"stone-wall",-6,-8},{"small-lamp",-6,-6}, + {"iron-chest",-6,0},{"iron-chest",-6,3},{"small-lamp",-6,9},{"stone-wall",-6,11},{"stone-wall",-5,-8},{"small-lamp",-5,-1},{"iron-chest",-5,0},{"iron-chest",-5,3},{"small-lamp",-5,4},{"stone-wall",-5,11}, + {"stone-wall",-4,-8},{"small-electric-pole",-4,-5},{"iron-chest",-4,0},{"iron-chest",-4,3},{"small-electric-pole",-4,8},{"stone-wall",-4,11},{"stone-wall",-3,-8},{"small-lamp",-3,-6},{"small-lamp",-3,-3},{"small-lamp",-3,6}, + {"small-lamp",-3,9},{"stone-wall",-3,11},{"stone-wall",-2,-8},{"iron-chest",-2,-6},{"iron-chest",-2,-5},{"iron-chest",-2,-4},{"iron-chest",-2,-3},{"iron-chest",-2,-2},{"iron-chest",-2,5},{"iron-chest",-2,6}, + {"iron-chest",-2,7},{"iron-chest",-2,8},{"iron-chest",-2,9},{"stone-wall",-2,11},{"stone-wall",1,-8},{"iron-chest",1,-6}, + {"iron-chest",1,-5},{"iron-chest",1,-4},{"iron-chest",1,-3},{"iron-chest",1,-2},{"iron-chest",1,5},{"iron-chest",1,6},{"iron-chest",1,7},{"iron-chest",1,8},{"iron-chest",1,9},{"stone-wall",1,11}, + {"stone-wall",2,-8},{"small-lamp",2,-6},{"small-lamp",2,-3},{"small-lamp",2,6},{"small-lamp",2,9},{"stone-wall",2,11},{"stone-wall",3,-8},{"small-electric-pole",3,-5},{"iron-chest",3,0},{"iron-chest",3,3}, + {"small-electric-pole",3,8},{"stone-wall",3,11},{"stone-wall",4,-8},{"small-lamp",4,-1},{"iron-chest",4,0},{"iron-chest",4,3},{"small-lamp",4,4},{"stone-wall",4,11},{"stone-wall",5,-8},{"small-lamp",5,-6}, + {"iron-chest",5,0},{"iron-chest",5,3},{"small-lamp",5,9},{"stone-wall",5,11},{"stone-wall",6,-8},{"small-electric-pole",6,-2},{"iron-chest",6,0},{"iron-chest",6,3},{"small-electric-pole",6,5},{"stone-wall",6,11}, + {"stone-wall",7,-8},{"small-lamp",7,-4},{"small-lamp",7,-1},{"iron-chest",7,0},{"iron-chest",7,3},{"small-lamp",7,4},{"small-lamp",7,7},{"stone-wall",7,11},{"stone-wall",9,-6},{"stone-wall",9,-5}, + {"stone-wall",9,-4},{"stone-wall",9,-3},{"stone-wall",9,-2},{"stone-wall",9,-1},{"stone-wall",9,0},{"stone-wall",9,3},{"stone-wall",9,4},{"stone-wall",9,5},{"stone-wall",9,6},{"stone-wall",9,7}, + {"stone-wall",9,8},{"stone-wall",9,9} +} \ No newline at end of file diff --git a/modules/SpawnArea/src/spawn_tiles.lua b/modules/SpawnArea/src/spawn_tiles.lua new file mode 100644 index 00000000..77aa62c6 --- /dev/null +++ b/modules/SpawnArea/src/spawn_tiles.lua @@ -0,0 +1,109 @@ +return { + {-49,-3},{-49,-2},{-49,1},{-49,2},{-49,5},{-49,6},{-48,-4},{-48,-3},{-48,-2},{-48,1},{-48,2},{-48,5},{-48,6},{-48,7},{-47,-7},{-47,-6},{-47,-5},{-47,-4},{-47,-3},{-47,-2},{-47,5},{-47,6},{-47,7},{-47,8},{-47,9},{-47,10},{-46,-8},{-46,-7},{-46,-6},{-46,-5}, + {-46,-4},{-46,-3},{-46,-2},{-46,-1},{-46,4},{-46,5},{-46,6},{-46,7},{-46,8},{-46,9},{-46,10},{-46,11},{-45,-17},{-45,-16},{-45,-15},{-45,-14},{-45,-13},{-45,-12},{-45,-9},{-45,-8},{-45,-7},{-45,-2},{-45,-1},{-45,0},{-45,1},{-45,2},{-45,3},{-45,4},{-45,5},{-45,10}, + {-45,11},{-45,12},{-45,15},{-45,16},{-45,17},{-45,18},{-45,19},{-45,20},{-44,-18},{-44,-17},{-44,-16},{-44,-15},{-44,-14},{-44,-13},{-44,-12},{-44,-9},{-44,-8},{-44,-1},{-44,0},{-44,1},{-44,2},{-44,3},{-44,4},{-44,11},{-44,12},{-44,15},{-44,16},{-44,17},{-44,18},{-44,19}, + {-44,20},{-44,21},{-43,-19},{-43,-18},{-43,-17},{-43,-1},{-43,0},{-43,1},{-43,2},{-43,3},{-43,4},{-43,20},{-43,21},{-43,22},{-42,-19},{-42,-18},{-42,-1},{-42,0},{-42,1},{-42,2},{-42,3},{-42,4},{-42,21},{-42,22},{-41,-25},{-41,-24},{-41,-19},{-41,-18},{-41,-13},{-41,-12}, + {-41,-11},{-41,-10},{-41,-5},{-41,-4},{-41,7},{-41,8},{-41,13},{-41,14},{-41,15},{-41,16},{-41,21},{-41,22},{-41,27},{-41,28},{-40,-26},{-40,-25},{-40,-24},{-40,-20},{-40,-19},{-40,-18},{-40,-13},{-40,-12},{-40,-11},{-40,-10},{-40,-5},{-40,-4},{-40,7},{-40,8},{-40,13},{-40,14}, + {-40,15},{-40,16},{-40,21},{-40,22},{-40,23},{-40,27},{-40,28},{-40,29},{-39,-27},{-39,-26},{-39,-25},{-39,-24},{-39,-21},{-39,-20},{-39,-19},{-39,-13},{-39,-12},{-39,-5},{-39,-4},{-39,-3},{-39,-2},{-39,-1},{-39,0},{-39,1},{-39,2},{-39,3},{-39,4},{-39,5},{-39,6},{-39,7}, + {-39,8},{-39,15},{-39,16},{-39,22},{-39,23},{-39,24},{-39,27},{-39,28},{-39,29},{-39,30},{-38,-27},{-38,-26},{-38,-25},{-38,-24},{-38,-21},{-38,-20},{-38,-13},{-38,-12},{-38,-5},{-38,-4},{-38,-3},{-38,-2},{-38,-1},{-38,0},{-38,1},{-38,2},{-38,3},{-38,4},{-38,5},{-38,6}, + {-38,7},{-38,8},{-38,15},{-38,16},{-38,23},{-38,24},{-38,27},{-38,28},{-38,29},{-38,30},{-37,-17},{-37,-16},{-37,-13},{-37,-12},{-37,-11},{-37,-10},{-37,-4},{-37,-3},{-37,-2},{-37,-1},{-37,0},{-37,3},{-37,4},{-37,5},{-37,6},{-37,7},{-37,13},{-37,14},{-37,15},{-37,16}, + {-37,19},{-37,20},{-36,-17},{-36,-16},{-36,-13},{-36,-12},{-36,-11},{-36,-10},{-36,-9},{-36,-3},{-36,-2},{-36,-1},{-36,0},{-36,3},{-36,4},{-36,5},{-36,6},{-36,12},{-36,13},{-36,14},{-36,15},{-36,16},{-36,19},{-36,20},{-35,-29},{-35,-28},{-35,-23},{-35,-22},{-35,-17},{-35,-16}, + {-35,-12},{-35,-11},{-35,-10},{-35,-9},{-35,-8},{-35,11},{-35,12},{-35,13},{-35,14},{-35,15},{-35,19},{-35,20},{-35,25},{-35,26},{-35,31},{-35,32},{-34,-30},{-34,-29},{-34,-28},{-34,-23},{-34,-22},{-34,-17},{-34,-16},{-34,-15},{-34,-11},{-34,-10},{-34,-9},{-34,-8},{-34,11},{-34,12}, + {-34,13},{-34,14},{-34,18},{-34,19},{-34,20},{-34,25},{-34,26},{-34,31},{-34,32},{-34,33},{-33,-31},{-33,-30},{-33,-29},{-33,-28},{-33,-23},{-33,-22},{-33,-16},{-33,-15},{-33,-14},{-33,-5},{-33,-4},{-33,-1},{-33,0},{-33,3},{-33,4},{-33,7},{-33,8},{-33,17},{-33,18},{-33,19}, + {-33,25},{-33,26},{-33,31},{-33,32},{-33,33},{-33,34},{-32,-32},{-32,-31},{-32,-30},{-32,-29},{-32,-28},{-32,-27},{-32,-23},{-32,-22},{-32,-21},{-32,-15},{-32,-14},{-32,-6},{-32,-5},{-32,-4},{-32,-1},{-32,0},{-32,3},{-32,4},{-32,7},{-32,8},{-32,9},{-32,17},{-32,18},{-32,24}, + {-32,25},{-32,26},{-32,30},{-32,31},{-32,32},{-32,33},{-32,34},{-32,35},{-31,-33},{-31,-32},{-31,-31},{-31,-30},{-31,-29},{-31,-28},{-31,-27},{-31,-26},{-31,-22},{-31,-21},{-31,-20},{-31,-19},{-31,-18},{-31,-11},{-31,-10},{-31,-9},{-31,-8},{-31,-7},{-31,-6},{-31,-5},{-31,-1},{-31,0}, + {-31,1},{-31,2},{-31,3},{-31,4},{-31,8},{-31,9},{-31,10},{-31,11},{-31,12},{-31,13},{-31,14},{-31,21},{-31,22},{-31,23},{-31,24},{-31,25},{-31,29},{-31,30},{-31,31},{-31,32},{-31,33},{-31,34},{-31,35},{-31,36},{-30,-33},{-30,-32},{-30,-31},{-30,-30},{-30,-29},{-30,-28}, + {-30,-27},{-30,-26},{-30,-21},{-30,-20},{-30,-19},{-30,-18},{-30,-11},{-30,-10},{-30,-9},{-30,-8},{-30,-7},{-30,-6},{-30,-1},{-30,0},{-30,1},{-30,2},{-30,3},{-30,4},{-30,9},{-30,10},{-30,11},{-30,12},{-30,13},{-30,14},{-30,21},{-30,22},{-30,23},{-30,24},{-30,29},{-30,30}, + {-30,31},{-30,32},{-30,33},{-30,34},{-30,35},{-30,36},{-29,-37},{-29,-36},{-29,-30},{-29,-29},{-29,-28},{-29,-27},{-29,-26},{-29,-15},{-29,-14},{-29,-10},{-29,-9},{-29,-8},{-29,-7},{-29,10},{-29,11},{-29,12},{-29,13},{-29,17},{-29,18},{-29,29},{-29,30},{-29,31},{-29,32},{-29,33}, + {-29,39},{-29,40},{-28,-38},{-28,-37},{-28,-36},{-28,-29},{-28,-28},{-28,-27},{-28,-26},{-28,-16},{-28,-15},{-28,-14},{-28,-9},{-28,-8},{-28,11},{-28,12},{-28,17},{-28,18},{-28,19},{-28,29},{-28,30},{-28,31},{-28,32},{-28,39},{-28,40},{-28,41},{-27,-39},{-27,-38},{-27,-37},{-27,-36}, + {-27,-23},{-27,-22},{-27,-19},{-27,-18},{-27,-17},{-27,-16},{-27,-15},{-27,-5},{-27,-4},{-27,-1},{-27,0},{-27,1},{-27,2},{-27,3},{-27,4},{-27,7},{-27,8},{-27,18},{-27,19},{-27,20},{-27,21},{-27,22},{-27,25},{-27,26},{-27,39},{-27,40},{-27,41},{-27,42},{-26,-39},{-26,-38}, + {-26,-37},{-26,-36},{-26,-24},{-26,-23},{-26,-22},{-26,-19},{-26,-18},{-26,-17},{-26,-16},{-26,-6},{-26,-5},{-26,-4},{-26,-1},{-26,0},{-26,1},{-26,2},{-26,3},{-26,4},{-26,7},{-26,8},{-26,9},{-26,19},{-26,20},{-26,21},{-26,22},{-26,25},{-26,26},{-26,27},{-26,39},{-26,40}, + {-26,41},{-26,42},{-25,-33},{-25,-32},{-25,-31},{-25,-30},{-25,-25},{-25,-24},{-25,-23},{-25,-22},{-25,-19},{-25,-18},{-25,-17},{-25,-9},{-25,-8},{-25,-7},{-25,-6},{-25,-5},{-25,-4},{-25,-1},{-25,0},{-25,1},{-25,2},{-25,3},{-25,4},{-25,7},{-25,8},{-25,9},{-25,10},{-25,11}, + {-25,12},{-25,20},{-25,21},{-25,22},{-25,25},{-25,26},{-25,27},{-25,28},{-25,33},{-25,34},{-25,35},{-25,36},{-24,-33},{-24,-32},{-24,-31},{-24,-30},{-24,-29},{-24,-25},{-24,-24},{-24,-23},{-24,-22},{-24,-19},{-24,-18},{-24,-9},{-24,-8},{-24,-7},{-24,-6},{-24,-5},{-24,-4},{-24,-1}, + {-24,0},{-24,1},{-24,2},{-24,3},{-24,4},{-24,7},{-24,8},{-24,9},{-24,10},{-24,11},{-24,12},{-24,21},{-24,22},{-24,25},{-24,26},{-24,27},{-24,28},{-24,32},{-24,33},{-24,34},{-24,35},{-24,36},{-23,-37},{-23,-36},{-23,-30},{-23,-29},{-23,-28},{-23,-19},{-23,-18},{-23,-15}, + {-23,-14},{-23,-9},{-23,-8},{-23,-7},{-23,-6},{-23,-5},{-23,0},{-23,1},{-23,2},{-23,3},{-23,8},{-23,9},{-23,10},{-23,11},{-23,12},{-23,17},{-23,18},{-23,21},{-23,22},{-23,31},{-23,32},{-23,33},{-23,39},{-23,40},{-22,-38},{-22,-37},{-22,-36},{-22,-29},{-22,-28},{-22,-19}, + {-22,-18},{-22,-15},{-22,-14},{-22,-13},{-22,-9},{-22,-8},{-22,-7},{-22,-6},{-22,1},{-22,2},{-22,9},{-22,10},{-22,11},{-22,12},{-22,16},{-22,17},{-22,18},{-22,21},{-22,22},{-22,31},{-22,32},{-22,39},{-22,40},{-22,41},{-21,-41},{-21,-40},{-21,-39},{-21,-38},{-21,-37},{-21,-29}, + {-21,-28},{-21,-25},{-21,-24},{-21,-23},{-21,-22},{-21,-21},{-21,-20},{-21,-19},{-21,-18},{-21,-15},{-21,-14},{-21,-13},{-21,-12},{-21,-3},{-21,-2},{-21,5},{-21,6},{-21,15},{-21,16},{-21,17},{-21,18},{-21,21},{-21,22},{-21,23},{-21,24},{-21,25},{-21,26},{-21,27},{-21,28},{-21,31}, + {-21,32},{-21,40},{-21,41},{-21,42},{-21,43},{-21,44},{-20,-42},{-20,-41},{-20,-40},{-20,-39},{-20,-38},{-20,-29},{-20,-28},{-20,-25},{-20,-24},{-20,-23},{-20,-22},{-20,-21},{-20,-20},{-20,-19},{-20,-18},{-20,-15},{-20,-14},{-20,-13},{-20,-12},{-20,-3},{-20,-2},{-20,-1},{-20,4},{-20,5}, + {-20,6},{-20,15},{-20,16},{-20,17},{-20,18},{-20,21},{-20,22},{-20,23},{-20,24},{-20,25},{-20,26},{-20,27},{-20,28},{-20,31},{-20,32},{-20,41},{-20,42},{-20,43},{-20,44},{-20,45},{-19,-43},{-19,-42},{-19,-41},{-19,-35},{-19,-34},{-19,-33},{-19,-32},{-19,-25},{-19,-24},{-19,-23}, + {-19,-15},{-19,-14},{-19,-13},{-19,-9},{-19,-8},{-19,-7},{-19,-6},{-19,-2},{-19,-1},{-19,0},{-19,1},{-19,2},{-19,3},{-19,4},{-19,5},{-19,9},{-19,10},{-19,11},{-19,12},{-19,16},{-19,17},{-19,18},{-19,26},{-19,27},{-19,28},{-19,35},{-19,36},{-19,37},{-19,38},{-19,44}, + {-19,45},{-19,46},{-18,-43},{-18,-42},{-18,-35},{-18,-34},{-18,-33},{-18,-32},{-18,-31},{-18,-26},{-18,-25},{-18,-24},{-18,-15},{-18,-14},{-18,-10},{-18,-9},{-18,-8},{-18,-7},{-18,-6},{-18,-1},{-18,0},{-18,1},{-18,2},{-18,3},{-18,4},{-18,9},{-18,10},{-18,11},{-18,12},{-18,13}, + {-18,17},{-18,18},{-18,27},{-18,28},{-18,29},{-18,34},{-18,35},{-18,36},{-18,37},{-18,38},{-18,45},{-18,46},{-17,-43},{-17,-42},{-17,-32},{-17,-31},{-17,-30},{-17,-27},{-17,-26},{-17,-25},{-17,-21},{-17,-20},{-17,-19},{-17,-18},{-17,-17},{-17,-16},{-17,-15},{-17,-14},{-17,-11},{-17,-10}, + {-17,-9},{-17,-8},{-17,-7},{-17,-6},{-17,0},{-17,1},{-17,2},{-17,3},{-17,9},{-17,10},{-17,11},{-17,12},{-17,13},{-17,14},{-17,17},{-17,18},{-17,19},{-17,20},{-17,21},{-17,22},{-17,23},{-17,24},{-17,28},{-17,29},{-17,30},{-17,33},{-17,34},{-17,35},{-17,45},{-17,46}, + {-16,-43},{-16,-42},{-16,-31},{-16,-30},{-16,-27},{-16,-26},{-16,-21},{-16,-20},{-16,-19},{-16,-18},{-16,-17},{-16,-16},{-16,-15},{-16,-14},{-16,-11},{-16,-10},{-16,-9},{-16,-8},{-16,-7},{-16,-6},{-16,1},{-16,2},{-16,9},{-16,10},{-16,11},{-16,12},{-16,13},{-16,14},{-16,17},{-16,18}, + {-16,19},{-16,20},{-16,21},{-16,22},{-16,23},{-16,24},{-16,29},{-16,30},{-16,33},{-16,34},{-16,45},{-16,46},{-15,-43},{-15,-42},{-15,-39},{-15,-38},{-15,-37},{-15,-36},{-15,-35},{-15,-34},{-15,-20},{-15,-19},{-15,-18},{-15,-17},{-15,-10},{-15,-9},{-15,-8},{-15,-7},{-15,-3},{-15,-2}, + {-15,1},{-15,2},{-15,5},{-15,6},{-15,10},{-15,11},{-15,12},{-15,13},{-15,20},{-15,21},{-15,22},{-15,23},{-15,37},{-15,38},{-15,39},{-15,40},{-15,41},{-15,42},{-15,45},{-15,46},{-14,-43},{-14,-42},{-14,-39},{-14,-38},{-14,-37},{-14,-36},{-14,-35},{-14,-34},{-14,-33},{-14,-19}, + {-14,-18},{-14,-9},{-14,-8},{-14,-4},{-14,-3},{-14,-2},{-14,1},{-14,2},{-14,5},{-14,6},{-14,7},{-14,11},{-14,12},{-14,21},{-14,22},{-14,36},{-14,37},{-14,38},{-14,39},{-14,40},{-14,41},{-14,42},{-14,45},{-14,46},{-13,-39},{-13,-38},{-13,-35},{-13,-34},{-13,-33},{-13,-32}, + {-13,-29},{-13,-28},{-13,-15},{-13,-14},{-13,-5},{-13,-4},{-13,-3},{-13,-2},{-13,5},{-13,6},{-13,7},{-13,8},{-13,17},{-13,18},{-13,31},{-13,32},{-13,35},{-13,36},{-13,37},{-13,38},{-13,41},{-13,42},{-12,-39},{-12,-38},{-12,-35},{-12,-34},{-12,-33},{-12,-32},{-12,-29},{-12,-28}, + {-12,-27},{-12,-16},{-12,-15},{-12,-14},{-12,-13},{-12,-5},{-12,-4},{-12,-3},{-12,-2},{-12,5},{-12,6},{-12,7},{-12,8},{-12,16},{-12,17},{-12,18},{-12,19},{-12,30},{-12,31},{-12,32},{-12,35},{-12,36},{-12,37},{-12,38},{-12,41},{-12,42},{-11,-43},{-11,-42},{-11,-34},{-11,-33}, + {-11,-32},{-11,-29},{-11,-28},{-11,-27},{-11,-26},{-11,-23},{-11,-22},{-11,-21},{-11,-20},{-11,-17},{-11,-16},{-11,-15},{-11,-14},{-11,-13},{-11,-12},{-11,-9},{-11,-8},{-11,1},{-11,2},{-11,11},{-11,12},{-11,15},{-11,16},{-11,17},{-11,18},{-11,19},{-11,20},{-11,23},{-11,24},{-11,25}, + {-11,26},{-11,29},{-11,30},{-11,31},{-11,32},{-11,35},{-11,36},{-11,37},{-11,45},{-11,46},{-10,-44},{-10,-43},{-10,-42},{-10,-33},{-10,-32},{-10,-29},{-10,-28},{-10,-27},{-10,-26},{-10,-23},{-10,-22},{-10,-21},{-10,-20},{-10,-17},{-10,-16},{-10,-15},{-10,-14},{-10,-13},{-10,-12},{-10,-9}, + {-10,-8},{-10,-7},{-10,0},{-10,1},{-10,2},{-10,3},{-10,10},{-10,11},{-10,12},{-10,15},{-10,16},{-10,17},{-10,18},{-10,19},{-10,20},{-10,23},{-10,24},{-10,25},{-10,26},{-10,29},{-10,30},{-10,31},{-10,32},{-10,35},{-10,36},{-10,45},{-10,46},{-10,47},{-9,-45},{-9,-44}, + {-9,-43},{-9,-29},{-9,-28},{-9,-27},{-9,-23},{-9,-22},{-9,-21},{-9,-20},{-9,-17},{-9,-16},{-9,-15},{-9,-14},{-9,-13},{-9,-8},{-9,-7},{-9,-6},{-9,-5},{-9,-1},{-9,0},{-9,1},{-9,2},{-9,3},{-9,4},{-9,8},{-9,9},{-9,10},{-9,11},{-9,16},{-9,17},{-9,18}, + {-9,19},{-9,20},{-9,23},{-9,24},{-9,25},{-9,26},{-9,30},{-9,31},{-9,32},{-9,46},{-9,47},{-9,48},{-8,-45},{-8,-44},{-8,-30},{-8,-29},{-8,-28},{-8,-24},{-8,-23},{-8,-22},{-8,-21},{-8,-20},{-8,-17},{-8,-16},{-8,-15},{-8,-14},{-8,-7},{-8,-6},{-8,-5},{-8,-4}, + {-8,-1},{-8,0},{-8,1},{-8,2},{-8,3},{-8,4},{-8,7},{-8,8},{-8,9},{-8,10},{-8,17},{-8,18},{-8,19},{-8,20},{-8,23},{-8,24},{-8,25},{-8,26},{-8,27},{-8,31},{-8,32},{-8,33},{-8,47},{-8,48},{-7,-45},{-7,-44},{-7,-39},{-7,-38},{-7,-37},{-7,-36}, + {-7,-31},{-7,-30},{-7,-29},{-7,-25},{-7,-24},{-7,-23},{-7,-22},{-7,-21},{-7,-11},{-7,-10},{-7,-7},{-7,-6},{-7,-5},{-7,-4},{-7,7},{-7,8},{-7,9},{-7,10},{-7,13},{-7,14},{-7,24},{-7,25},{-7,26},{-7,27},{-7,28},{-7,32},{-7,33},{-7,34},{-7,39},{-7,40}, + {-7,41},{-7,42},{-7,47},{-7,48},{-6,-46},{-6,-45},{-6,-44},{-6,-39},{-6,-38},{-6,-37},{-6,-36},{-6,-35},{-6,-31},{-6,-30},{-6,-25},{-6,-24},{-6,-23},{-6,-22},{-6,-12},{-6,-11},{-6,-10},{-6,-6},{-6,-5},{-6,8},{-6,9},{-6,13},{-6,14},{-6,15},{-6,25},{-6,26}, + {-6,27},{-6,28},{-6,33},{-6,34},{-6,38},{-6,39},{-6,40},{-6,41},{-6,42},{-6,47},{-6,48},{-6,49},{-5,-47},{-5,-46},{-5,-45},{-5,-44},{-5,-37},{-5,-36},{-5,-35},{-5,-34},{-5,-19},{-5,-18},{-5,-13},{-5,-12},{-5,-11},{-5,-10},{-5,-1},{-5,0},{-5,1},{-5,2}, + {-5,3},{-5,4},{-5,13},{-5,14},{-5,15},{-5,16},{-5,21},{-5,22},{-5,37},{-5,38},{-5,39},{-5,40},{-5,47},{-5,48},{-5,49},{-5,50},{-4,-47},{-4,-46},{-4,-45},{-4,-44},{-4,-43},{-4,-37},{-4,-36},{-4,-35},{-4,-34},{-4,-19},{-4,-18},{-4,-17},{-4,-13},{-4,-12}, + {-4,-11},{-4,-10},{-4,-2},{-4,-1},{-4,0},{-4,1},{-4,2},{-4,3},{-4,4},{-4,5},{-4,13},{-4,14},{-4,15},{-4,16},{-4,20},{-4,21},{-4,22},{-4,37},{-4,38},{-4,39},{-4,40},{-4,46},{-4,47},{-4,48},{-4,49},{-4,50},{-3,-44},{-3,-43},{-3,-42},{-3,-41}, + {-3,-40},{-3,-37},{-3,-36},{-3,-35},{-3,-34},{-3,-31},{-3,-30},{-3,-29},{-3,-28},{-3,-25},{-3,-24},{-3,-23},{-3,-22},{-3,-18},{-3,-17},{-3,-16},{-3,-7},{-3,-6},{-3,-3},{-3,-2},{-3,-1},{-3,0},{-3,3},{-3,4},{-3,5},{-3,6},{-3,9},{-3,10},{-3,19},{-3,20}, + {-3,21},{-3,25},{-3,26},{-3,27},{-3,28},{-3,31},{-3,32},{-3,33},{-3,34},{-3,37},{-3,38},{-3,39},{-3,40},{-3,43},{-3,44},{-3,45},{-3,46},{-3,47},{-2,-43},{-2,-42},{-2,-41},{-2,-40},{-2,-37},{-2,-36},{-2,-35},{-2,-34},{-2,-31},{-2,-30},{-2,-29},{-2,-28}, + {-2,-25},{-2,-24},{-2,-23},{-2,-22},{-2,-21},{-2,-17},{-2,-16},{-2,-15},{-2,-8},{-2,-7},{-2,-6},{-2,-3},{-2,-2},{-2,-1},{-2,0},{-2,3},{-2,4},{-2,5},{-2,6},{-2,9},{-2,10},{-2,11},{-2,18},{-2,19},{-2,20},{-2,24},{-2,25},{-2,26},{-2,27},{-2,28}, + {-2,31},{-2,32},{-2,33},{-2,34},{-2,37},{-2,38},{-2,39},{-2,40},{-2,43},{-2,44},{-2,45},{-2,46},{-1,-47},{-1,-46},{-1,-43},{-1,-42},{-1,-41},{-1,-40},{-1,-37},{-1,-36},{-1,-29},{-1,-28},{-1,-25},{-1,-24},{-1,-23},{-1,-22},{-1,-21},{-1,-20},{-1,-17},{-1,-16}, + {-1,-15},{-1,-14},{-1,-13},{-1,-12},{-1,-9},{-1,-8},{-1,-7},{-1,-6},{-1,-3},{-1,-2},{-1,5},{-1,6},{-1,9},{-1,10},{-1,11},{-1,12},{-1,15},{-1,16},{-1,17},{-1,18},{-1,19},{-1,20},{-1,23},{-1,24},{-1,25},{-1,26},{-1,27},{-1,28},{-1,31},{-1,32}, + {-1,39},{-1,40},{-1,43},{-1,44},{-1,45},{-1,46},{-1,49},{-1,50},{0,-47},{0,-46},{0,-43},{0,-42},{0,-41},{0,-40},{0,-37},{0,-36},{0,-29},{0,-28},{0,-25},{0,-24},{0,-23},{0,-22},{0,-21},{0,-20},{0,-17},{0,-16},{0,-15},{0,-14},{0,-13},{0,-12}, + {0,-9},{0,-8},{0,-7},{0,-6},{0,-3},{0,-2},{0,5},{0,6},{0,9},{0,10},{0,11},{0,12},{0,15},{0,16},{0,17},{0,18},{0,19},{0,20},{0,23},{0,24},{0,25},{0,26},{0,27},{0,28},{0,31},{0,32},{0,39},{0,40},{0,43},{0,44}, + {0,45},{0,46},{0,49},{0,50},{1,-43},{1,-42},{1,-41},{1,-40},{1,-37},{1,-36},{1,-35},{1,-34},{1,-31},{1,-30},{1,-29},{1,-28},{1,-25},{1,-24},{1,-23},{1,-22},{1,-21},{1,-17},{1,-16},{1,-15},{1,-8},{1,-7},{1,-6},{1,-3},{1,-2},{1,-1}, + {1,0},{1,3},{1,4},{1,5},{1,6},{1,9},{1,10},{1,11},{1,18},{1,19},{1,20},{1,24},{1,25},{1,26},{1,27},{1,28},{1,31},{1,32},{1,33},{1,34},{1,37},{1,38},{1,39},{1,40},{1,43},{1,44},{1,45},{1,46},{2,-44},{2,-43}, + {2,-42},{2,-41},{2,-40},{2,-37},{2,-36},{2,-35},{2,-34},{2,-31},{2,-30},{2,-29},{2,-28},{2,-25},{2,-24},{2,-23},{2,-22},{2,-18},{2,-17},{2,-16},{2,-7},{2,-6},{2,-3},{2,-2},{2,-1},{2,0},{2,3},{2,4},{2,5},{2,6},{2,9},{2,10}, + {2,19},{2,20},{2,21},{2,25},{2,26},{2,27},{2,28},{2,31},{2,32},{2,33},{2,34},{2,37},{2,38},{2,39},{2,40},{2,43},{2,44},{2,45},{2,46},{2,47},{3,-47},{3,-46},{3,-45},{3,-44},{3,-43},{3,-37},{3,-36},{3,-35},{3,-34},{3,-19}, + {3,-18},{3,-17},{3,-13},{3,-12},{3,-11},{3,-10},{3,-2},{3,-1},{3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,13},{3,14},{3,15},{3,16},{3,20},{3,21},{3,22},{3,37},{3,38},{3,39},{3,40},{3,46},{3,47},{3,48},{3,49},{3,50}, + {4,-47},{4,-46},{4,-45},{4,-44},{4,-37},{4,-36},{4,-35},{4,-34},{4,-19},{4,-18},{4,-13},{4,-12},{4,-11},{4,-10},{4,-1},{4,0},{4,1},{4,2},{4,3},{4,4},{4,13},{4,14},{4,15},{4,16},{4,21},{4,22},{4,37},{4,38},{4,39},{4,40}, + {4,47},{4,48},{4,49},{4,50},{5,-46},{5,-45},{5,-44},{5,-39},{5,-38},{5,-37},{5,-36},{5,-35},{5,-31},{5,-30},{5,-25},{5,-24},{5,-23},{5,-22},{5,-12},{5,-11},{5,-10},{5,-6},{5,-5},{5,8},{5,9},{5,13},{5,14},{5,15},{5,25},{5,26}, + {5,27},{5,28},{5,33},{5,34},{5,38},{5,39},{5,40},{5,41},{5,42},{5,47},{5,48},{5,49},{6,-45},{6,-44},{6,-39},{6,-38},{6,-37},{6,-36},{6,-31},{6,-30},{6,-29},{6,-25},{6,-24},{6,-23},{6,-22},{6,-21},{6,-11},{6,-10},{6,-7},{6,-6}, + {6,-5},{6,-4},{6,7},{6,8},{6,9},{6,10},{6,13},{6,14},{6,24},{6,25},{6,26},{6,27},{6,28},{6,32},{6,33},{6,34},{6,39},{6,40},{6,41},{6,42},{6,47},{6,48},{7,-45},{7,-44},{7,-30},{7,-29},{7,-28},{7,-24},{7,-23},{7,-22}, + {7,-21},{7,-20},{7,-17},{7,-16},{7,-15},{7,-14},{7,-7},{7,-6},{7,-5},{7,-4},{7,-1},{7,0},{7,1},{7,2},{7,3},{7,4},{7,7},{7,8},{7,9},{7,10},{7,17},{7,18},{7,19},{7,20},{7,23},{7,24},{7,25},{7,26},{7,27},{7,31}, + {7,32},{7,33},{7,47},{7,48},{8,-45},{8,-44},{8,-43},{8,-29},{8,-28},{8,-27},{8,-23},{8,-22},{8,-21},{8,-20},{8,-17},{8,-16},{8,-15},{8,-14},{8,-13},{8,-8},{8,-7},{8,-6},{8,-5},{8,-1},{8,0},{8,1},{8,2},{8,3},{8,4},{8,8}, + {8,9},{8,10},{8,11},{8,16},{8,17},{8,18},{8,19},{8,20},{8,23},{8,24},{8,25},{8,26},{8,30},{8,31},{8,32},{8,46},{8,47},{8,48},{9,-44},{9,-43},{9,-42},{9,-33},{9,-32},{9,-29},{9,-28},{9,-27},{9,-26},{9,-23},{9,-22},{9,-21}, + {9,-20},{9,-17},{9,-16},{9,-15},{9,-14},{9,-13},{9,-12},{9,-9},{9,-8},{9,-7},{9,0},{9,1},{9,2},{9,3},{9,10},{9,11},{9,12},{9,15},{9,16},{9,17},{9,18},{9,19},{9,20},{9,23},{9,24},{9,25},{9,26},{9,29},{9,30},{9,31}, + {9,32},{9,35},{9,36},{9,45},{9,46},{9,47},{10,-43},{10,-42},{10,-34},{10,-33},{10,-32},{10,-29},{10,-28},{10,-27},{10,-26},{10,-23},{10,-22},{10,-21},{10,-20},{10,-17},{10,-16},{10,-15},{10,-14},{10,-13},{10,-12},{10,-9},{10,-8},{10,1},{10,2},{10,11}, + {10,12},{10,15},{10,16},{10,17},{10,18},{10,19},{10,20},{10,23},{10,24},{10,25},{10,26},{10,29},{10,30},{10,31},{10,32},{10,35},{10,36},{10,37},{10,45},{10,46},{11,-39},{11,-38},{11,-35},{11,-34},{11,-33},{11,-32},{11,-29},{11,-28},{11,-27},{11,-16}, + {11,-15},{11,-14},{11,-13},{11,-5},{11,-4},{11,-3},{11,-2},{11,5},{11,6},{11,7},{11,8},{11,16},{11,17},{11,18},{11,19},{11,30},{11,31},{11,32},{11,35},{11,36},{11,37},{11,38},{11,41},{11,42},{12,-39},{12,-38},{12,-35},{12,-34},{12,-33},{12,-32}, + {12,-29},{12,-28},{12,-15},{12,-14},{12,-5},{12,-4},{12,-3},{12,-2},{12,5},{12,6},{12,7},{12,8},{12,17},{12,18},{12,31},{12,32},{12,35},{12,36},{12,37},{12,38},{12,41},{12,42},{13,-43},{13,-42},{13,-39},{13,-38},{13,-37},{13,-36},{13,-35},{13,-34}, + {13,-33},{13,-19},{13,-18},{13,-9},{13,-8},{13,-4},{13,-3},{13,-2},{13,1},{13,2},{13,5},{13,6},{13,7},{13,11},{13,12},{13,21},{13,22},{13,36},{13,37},{13,38},{13,39},{13,40},{13,41},{13,42},{13,45},{13,46},{14,-43},{14,-42},{14,-39},{14,-38}, + {14,-37},{14,-36},{14,-35},{14,-34},{14,-20},{14,-19},{14,-18},{14,-17},{14,-10},{14,-9},{14,-8},{14,-7},{14,-3},{14,-2},{14,1},{14,2},{14,5},{14,6},{14,10},{14,11},{14,12},{14,13},{14,20},{14,21},{14,22},{14,23},{14,37},{14,38},{14,39},{14,40}, + {14,41},{14,42},{14,45},{14,46},{15,-43},{15,-42},{15,-31},{15,-30},{15,-27},{15,-26},{15,-21},{15,-20},{15,-19},{15,-18},{15,-17},{15,-16},{15,-15},{15,-14},{15,-11},{15,-10},{15,-9},{15,-8},{15,-7},{15,-6},{15,1},{15,2},{15,9},{15,10},{15,11},{15,12}, + {15,13},{15,14},{15,17},{15,18},{15,19},{15,20},{15,21},{15,22},{15,23},{15,24},{15,29},{15,30},{15,33},{15,34},{15,45},{15,46},{16,-43},{16,-42},{16,-32},{16,-31},{16,-30},{16,-27},{16,-26},{16,-25},{16,-21},{16,-20},{16,-19},{16,-18},{16,-17},{16,-16}, + {16,-15},{16,-14},{16,-11},{16,-10},{16,-9},{16,-8},{16,-7},{16,-6},{16,0},{16,1},{16,2},{16,3},{16,9},{16,10},{16,11},{16,12},{16,13},{16,14},{16,17},{16,18},{16,19},{16,20},{16,21},{16,22},{16,23},{16,24},{16,28},{16,29},{16,30},{16,33}, + {16,34},{16,35},{16,45},{16,46},{17,-43},{17,-42},{17,-35},{17,-34},{17,-33},{17,-32},{17,-31},{17,-26},{17,-25},{17,-24},{17,-15},{17,-14},{17,-10},{17,-9},{17,-8},{17,-7},{17,-6},{17,-1},{17,0},{17,1},{17,2},{17,3},{17,4},{17,9},{17,10},{17,11}, + {17,12},{17,13},{17,17},{17,18},{17,27},{17,28},{17,29},{17,34},{17,35},{17,36},{17,37},{17,38},{17,45},{17,46},{18,-43},{18,-42},{18,-41},{18,-35},{18,-34},{18,-33},{18,-32},{18,-25},{18,-24},{18,-23},{18,-15},{18,-14},{18,-13},{18,-9},{18,-8},{18,-7}, + {18,-6},{18,-2},{18,-1},{18,0},{18,1},{18,2},{18,3},{18,4},{18,5},{18,9},{18,10},{18,11},{18,12},{18,16},{18,17},{18,18},{18,26},{18,27},{18,28},{18,35},{18,36},{18,37},{18,38},{18,44},{18,45},{18,46},{19,-42},{19,-41},{19,-40},{19,-39}, + {19,-38},{19,-29},{19,-28},{19,-25},{19,-24},{19,-23},{19,-22},{19,-21},{19,-20},{19,-19},{19,-18},{19,-15},{19,-14},{19,-13},{19,-12},{19,-3},{19,-2},{19,-1},{19,4},{19,5},{19,6},{19,15},{19,16},{19,17},{19,18},{19,21},{19,22},{19,23},{19,24},{19,25}, + {19,26},{19,27},{19,28},{19,31},{19,32},{19,41},{19,42},{19,43},{19,44},{19,45},{20,-41},{20,-40},{20,-39},{20,-38},{20,-37},{20,-29},{20,-28},{20,-25},{20,-24},{20,-23},{20,-22},{20,-21},{20,-20},{20,-19},{20,-18},{20,-15},{20,-14},{20,-13},{20,-12},{20,-3}, + {20,-2},{20,5},{20,6},{20,15},{20,16},{20,17},{20,18},{20,21},{20,22},{20,23},{20,24},{20,25},{20,26},{20,27},{20,28},{20,31},{20,32},{20,40},{20,41},{20,42},{20,43},{20,44},{21,-38},{21,-37},{21,-36},{21,-29},{21,-28},{21,-19},{21,-18},{21,-15}, + {21,-14},{21,-13},{21,-9},{21,-8},{21,-7},{21,-6},{21,1},{21,2},{21,9},{21,10},{21,11},{21,12},{21,16},{21,17},{21,18},{21,21},{21,22},{21,31},{21,32},{21,39},{21,40},{21,41},{22,-37},{22,-36},{22,-30},{22,-29},{22,-28},{22,-19},{22,-18},{22,-15}, + {22,-14},{22,-9},{22,-8},{22,-7},{22,-6},{22,-5},{22,0},{22,1},{22,2},{22,3},{22,8},{22,9},{22,10},{22,11},{22,12},{22,17},{22,18},{22,21},{22,22},{22,31},{22,32},{22,33},{22,39},{22,40},{23,-33},{23,-32},{23,-31},{23,-30},{23,-29},{23,-25}, + {23,-24},{23,-23},{23,-22},{23,-19},{23,-18},{23,-9},{23,-8},{23,-7},{23,-6},{23,-5},{23,-4},{23,-1},{23,0},{23,1},{23,2},{23,3},{23,4},{23,7},{23,8},{23,9},{23,10},{23,11},{23,12},{23,21},{23,22},{23,25},{23,26},{23,27},{23,28},{23,32}, + {23,33},{23,34},{23,35},{23,36},{24,-33},{24,-32},{24,-31},{24,-30},{24,-25},{24,-24},{24,-23},{24,-22},{24,-19},{24,-18},{24,-17},{24,-9},{24,-8},{24,-7},{24,-6},{24,-5},{24,-4},{24,-1},{24,0},{24,1},{24,2},{24,3},{24,4},{24,7},{24,8},{24,9}, + {24,10},{24,11},{24,12},{24,20},{24,21},{24,22},{24,25},{24,26},{24,27},{24,28},{24,33},{24,34},{24,35},{24,36},{25,-39},{25,-38},{25,-37},{25,-36},{25,-24},{25,-23},{25,-22},{25,-19},{25,-18},{25,-17},{25,-16},{25,-6},{25,-5},{25,-4},{25,-1},{25,0}, + {25,1},{25,2},{25,3},{25,4},{25,7},{25,8},{25,9},{25,19},{25,20},{25,21},{25,22},{25,25},{25,26},{25,27},{25,39},{25,40},{25,41},{25,42},{26,-39},{26,-38},{26,-37},{26,-36},{26,-23},{26,-22},{26,-19},{26,-18},{26,-17},{26,-16},{26,-15},{26,-5}, + {26,-4},{26,-1},{26,0},{26,1},{26,2},{26,3},{26,4},{26,7},{26,8},{26,18},{26,19},{26,20},{26,21},{26,22},{26,25},{26,26},{26,39},{26,40},{26,41},{26,42},{27,-38},{27,-37},{27,-36},{27,-29},{27,-28},{27,-27},{27,-26},{27,-16},{27,-15},{27,-14}, + {27,-9},{27,-8},{27,11},{27,12},{27,17},{27,18},{27,19},{27,29},{27,30},{27,31},{27,32},{27,39},{27,40},{27,41},{28,-37},{28,-36},{28,-30},{28,-29},{28,-28},{28,-27},{28,-26},{28,-15},{28,-14},{28,-10},{28,-9},{28,-8},{28,-7},{28,10},{28,11},{28,12}, + {28,13},{28,17},{28,18},{28,29},{28,30},{28,31},{28,32},{28,33},{28,39},{28,40},{29,-33},{29,-32},{29,-31},{29,-30},{29,-29},{29,-28},{29,-27},{29,-26},{29,-21},{29,-20},{29,-19},{29,-18},{29,-11},{29,-10},{29,-9},{29,-8},{29,-7},{29,-6},{29,-1},{29,0}, + {29,1},{29,2},{29,3},{29,4},{29,9},{29,10},{29,11},{29,12},{29,13},{29,14},{29,21},{29,22},{29,23},{29,24},{29,29},{29,30},{29,31},{29,32},{29,33},{29,34},{29,35},{29,36},{30,-33},{30,-32},{30,-31},{30,-30},{30,-29},{30,-28},{30,-27},{30,-26}, + {30,-22},{30,-21},{30,-20},{30,-19},{30,-18},{30,-11},{30,-10},{30,-9},{30,-8},{30,-7},{30,-6},{30,-5},{30,-1},{30,0},{30,1},{30,2},{30,3},{30,4},{30,8},{30,9},{30,10},{30,11},{30,12},{30,13},{30,14},{30,21},{30,22},{30,23},{30,24},{30,25}, + {30,29},{30,30},{30,31},{30,32},{30,33},{30,34},{30,35},{30,36},{31,-32},{31,-31},{31,-30},{31,-29},{31,-28},{31,-27},{31,-23},{31,-22},{31,-21},{31,-15},{31,-14},{31,-6},{31,-5},{31,-4},{31,-1},{31,0},{31,3},{31,4},{31,7},{31,8},{31,9},{31,17}, + {31,18},{31,24},{31,25},{31,26},{31,30},{31,31},{31,32},{31,33},{31,34},{31,35},{32,-31},{32,-30},{32,-29},{32,-28},{32,-23},{32,-22},{32,-16},{32,-15},{32,-14},{32,-5},{32,-4},{32,-1},{32,0},{32,3},{32,4},{32,7},{32,8},{32,17},{32,18},{32,19}, + {32,25},{32,26},{32,31},{32,32},{32,33},{32,34},{33,-30},{33,-29},{33,-28},{33,-23},{33,-22},{33,-17},{33,-16},{33,-15},{33,-11},{33,-10},{33,-9},{33,-8},{33,11},{33,12},{33,13},{33,14},{33,18},{33,19},{33,20},{33,25},{33,26},{33,31},{33,32},{33,33}, + {34,-29},{34,-28},{34,-23},{34,-22},{34,-17},{34,-16},{34,-12},{34,-11},{34,-10},{34,-9},{34,-8},{34,11},{34,12},{34,13},{34,14},{34,15},{34,19},{34,20},{34,25},{34,26},{34,31},{34,32},{35,-17},{35,-16},{35,-13},{35,-12},{35,-11},{35,-10},{35,-9},{35,-3}, + {35,-2},{35,-1},{35,0},{35,3},{35,4},{35,5},{35,6},{35,12},{35,13},{35,14},{35,15},{35,16},{35,19},{35,20},{36,-17},{36,-16},{36,-13},{36,-12},{36,-11},{36,-10},{36,-4},{36,-3},{36,-2},{36,-1},{36,0},{36,3},{36,4},{36,5},{36,6},{36,7}, + {36,13},{36,14},{36,15},{36,16},{36,19},{36,20},{37,-27},{37,-26},{37,-25},{37,-24},{37,-21},{37,-20},{37,-13},{37,-12},{37,-5},{37,-4},{37,-3},{37,-2},{37,-1},{37,0},{37,1},{37,2},{37,3},{37,4},{37,5},{37,6},{37,7},{37,8},{37,15},{37,16}, + {37,23},{37,24},{37,27},{37,28},{37,29},{37,30},{38,-27},{38,-26},{38,-25},{38,-24},{38,-21},{38,-20},{38,-19},{38,-13},{38,-12},{38,-5},{38,-4},{38,-3},{38,-2},{38,-1},{38,0},{38,1},{38,2},{38,3},{38,4},{38,5},{38,6},{38,7},{38,8},{38,15}, + {38,16},{38,22},{38,23},{38,24},{38,27},{38,28},{38,29},{38,30},{39,-26},{39,-25},{39,-24},{39,-20},{39,-19},{39,-18},{39,-13},{39,-12},{39,-11},{39,-10},{39,-5},{39,-4},{39,7},{39,8},{39,13},{39,14},{39,15},{39,16},{39,21},{39,22},{39,23},{39,27}, + {39,28},{39,29},{40,-25},{40,-24},{40,-19},{40,-18},{40,-13},{40,-12},{40,-11},{40,-10},{40,-5},{40,-4},{40,7},{40,8},{40,13},{40,14},{40,15},{40,16},{40,21},{40,22},{40,27},{40,28},{41,-19},{41,-18},{41,-1},{41,0},{41,1},{41,2},{41,3},{41,4}, + {41,21},{41,22},{42,-19},{42,-18},{42,-17},{42,-1},{42,0},{42,1},{42,2},{42,3},{42,4},{42,20},{42,21},{42,22},{43,-18},{43,-17},{43,-16},{43,-15},{43,-14},{43,-13},{43,-12},{43,-9},{43,-8},{43,-1},{43,0},{43,1},{43,2},{43,3},{43,4},{43,11}, + {43,12},{43,15},{43,16},{43,17},{43,18},{43,19},{43,20},{43,21},{44,-17},{44,-16},{44,-15},{44,-14},{44,-13},{44,-12},{44,-9},{44,-8},{44,-7},{44,-2},{44,-1},{44,0},{44,1},{44,2},{44,3},{44,4},{44,5},{44,10},{44,11},{44,12},{44,15},{44,16}, + {44,17},{44,18},{44,19},{44,20},{45,-8},{45,-7},{45,-6},{45,-5},{45,-4},{45,-3},{45,-2},{45,-1},{45,4},{45,5},{45,6},{45,7},{45,8},{45,9},{45,10},{45,11},{46,-7},{46,-6},{46,-5},{46,-4},{46,-3},{46,-2},{46,5},{46,6},{46,7},{46,8}, + {46,9},{46,10},{47,-4},{47,-3},{47,-2},{47,1},{47,2},{47,5},{47,6},{47,7},{48,-3},{48,-2},{48,1},{48,2},{48,5},{48,6} +} \ No newline at end of file diff --git a/modules/WarpPoints/control.lua b/modules/WarpPoints/control.lua new file mode 100644 index 00000000..42874bd4 --- /dev/null +++ b/modules/WarpPoints/control.lua @@ -0,0 +1,248 @@ +--- Creates a warp point system which makes moving around large maps easier. +-- @module WarpPoints@4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Gui = require('ExpGamingCore.Gui') +local Game = require('FactorioStdLib.Game') +local Role -- ExpGamingCore.Role@^4.0.0 + +-- Local Variables +local warp_tiles = require(module_path..'/src/warp_tiles') +local warp_entities = require(module_path..'/src/warp_entities') + +local warp_radius = 4 +local spawn_warp_scale = 5 +local warp_tile = 'tutorial-grid' +local warp_limit = 60 +local warp_item = 'discharge-defense-equipment' +local global_offset = {x=0,y=0} +local warp_min_distance = 25 + +-- Module Define +local _global = global +local global +local module_verbose = false +local ThisModule = { + on_init=function(self) + if loaded_modules['ExpGamingCore.Role'] then Role = require('ExpGamingCore.Role') end + if loaded_modules['ExpGamingCore.Command'] then require(module_path..'/src/commands',{self=self,warps=global,warp_min_distance=warp_min_distance}) end + end +} + +-- Global Define +global = _global{ + warps={}, -- 0,0 is always a warp + cooldowns={} +} + +-- Function Define + +--- Removes a warp point from the list, and then updates the gui +-- @usage ThisModule.remove_warp_point(name) -- name cant be spawn +-- @tparam string name the name of the warp point +function ThisModule.remove_warp_point(name) + local warp = global.warps[name] + if not warp then return end + local surface = game.surfaces[warp.surface] + local offset = warp.position + local tiles = {} + -- clears the area where the warp was + for x = -warp_radius, warp_radius do + for y = -warp_radius, warp_radius do + if x^2+y^2 < (warp_radius+1)^2 then + table.insert(tiles,{name=warp.old_tile,position={x+offset.x,y+offset.y}}) + local entities = surface.find_entities_filtered{area={{x+offset.x-1,y+offset.y-1},{x+offset.x,y+offset.y}}} + for _,entity in pairs(entities) do if entity.name ~= 'player' then entity.destroy() end end + end + end + end + surface.set_tiles(tiles) + if warp.tag.valid then warp.tag.destroy() end + global.warps[name] = nil + ThisModule.Gui() +end + +--- Adds a warp point from the list, and then updates the gui +-- @usage ThisModule.make_warp_point({x=10,y=10},surface,force,name) +-- @tparam table position the position of the new warp point +-- @tparam surface surface the surface that the warp point is on +-- @tparam force force the force that the warp point will belong to +-- @tparam string name the name of the warp point to be made +function ThisModule.make_warp_point(position,surface,force,warpName) + local warp = global.warps[warpName] + if warp then return end + local offset = {x=math.floor(position.x),y=math.floor(position.y)} + local old_tile = surface.get_tile(offset).name + local base_tiles = {} + local tiles = {} + -- this makes a base plate to make the warp point + for x = -warp_radius, warp_radius do + for y = -warp_radius, warp_radius do + if x^2+y^2 < warp_radius^2 then + table.insert(base_tiles,{name=warp_tile,position={x+offset.x,y+offset.y}}) + end + end + end + surface.set_tiles(base_tiles) + -- this adds the pattern and entities + for _,pos in pairs(warp_tiles) do + table.insert(tiles,{name=warp_tile,position={pos[1]+offset.x+global_offset.x,pos[2]+offset.y+global_offset.y}}) + end + surface.set_tiles(tiles) + for _,entity in pairs(warp_entities) do + entity = surface.create_entity{name=entity[1],position={entity[2]+offset.x+global_offset.x,entity[3]+offset.y+global_offset.y},force='neutral'} + entity.destructible = false; entity.health = 0; entity.minable = false; entity.rotatable = false + end + -- creates a tag on the map for the wap point + local tag = force.add_chart_tag(surface,{ + position={offset.x+0.5,offset.y+0.5}, + text='Warp: '..warpName, + icon={type='item',name=warp_item} + }) + global.warps[warpName] = {tag=tag,surface=surface.index,position=tag.position,old_tile=old_tile} + local _temp = {Spawn=global.warps.Spawn} + global.warps.Spawn = nil + for name,data in pairs(table.keysort(global.warps)) do _temp[name] = data end + global.warps = _temp + ThisModule.Gui() +end + +local remove_warp = Gui.inputs{ + type='button', + name='remove-warp-point', + caption='utility/remove', + tooltip={'WarpPoints.remove-tooltip'} +}:on_event('click',function(event) + local name = event.element.parent.name + ThisModule.remove_warp_point(name) +end) + +local go_to_warp = Gui.inputs{ + type='button', + name='go-to-warp-point', + caption='utility/export_slot', + tooltip={'WarpPoints.go-to-tooltip'} +}:on_event('click',function(event) + local player = Game.get_player(event) + local cooldown = global.cooldowns[event.player_index] or 0 + local warp = global.warps[event.element.parent.name] + if cooldown > 0 then player_return({'WarpPoints.cooldown',cooldown},nil,event) return end + if player.vehicle then player.vehicle.set_driver(nil) end + if player.vehicle then player.vehicle.set_passenger(nil) end + if player.vehicle then return end + player.teleport(game.surfaces[warp.surface].find_non_colliding_position('player',warp.position,32,1),game.surfaces[warp.surface]) + if not Role and not player.admin or Role and not Role.allowed(player,'always-warp') then + event.element.parent.parent.parent.parent.style.visible = false + global.cooldowns[event.player_index] = warp_limit + end +end) + +ThisModule.Gui = Gui.left{ + name='warp-list', + caption='item/'..warp_item, + tooltip={'WarpPoints.tooltip'}, + draw=function(self,frame) + local player = Game.get_player(frame.player_index) + frame.caption={'WarpPoints.name'} + local warp_list = frame.add{ + type='scroll-pane', + direction='vertical', + vertical_scroll_policy='auto', + horizontal_scroll_policy='never' + } + warp_list.vertical_scroll_policy = 'auto' + warp_list.style.maximal_height = 150 + local table = warp_list.add{ + type='table', + column_count=2 + } + for name,warp in pairs(global.warps) do + if not warp.tag or not warp.tag.valid then + player.force.add_chart_tag(game.surfaces[warp.surface],{ + position=warp.position, + text='Warp: '..name, + icon={type='item',name=warp_item} + }) + end + table.add{ + type='label', + caption=name, + style='caption_label' + } + local _flow = table.add{ + type='flow', + name=name + } + local btn = go_to_warp(_flow) + btn.style.height = 20 + btn.style.width = 20 + if not Role and player.admin and name ~= 'Spawn' or Role and Role.allowed(player,'make-warp') and name ~= 'Spawn' then + local btn = remove_warp(_flow) + btn.style.height = 20 + btn.style.width = 20 + end + end + local cooldown = global.cooldowns[player.index] or 0 + if cooldown > 0 then frame.style.visible = false return + elseif not Role and player.admin or Role and Role.allowed(player,'always-warp') then return + elseif player.surface.get_tile(player.position).name == warp_tile + and player.surface.name == 'nauvis' + then return + elseif player.position.x^2+player.position.y^2 < (warp_radius*spawn_warp_scale)^2 then return + else frame.style.visible = false end + end, + can_open=function(player) + local cooldown = global.cooldowns[player.index] or 0 + if not Role and player.admin or Role and Role.allowed(player,'always-warp') then return true + elseif player.surface.get_tile(player.position).name == warp_tile + and player.surface.name == 'nauvis' + then return true + elseif player.position.x^2+player.position.y^2 < (warp_radius*spawn_warp_scale)^2 then return true + elseif cooldown > 0 then return {'WarpPoints.cooldown',cooldown} + else return {'WarpPoints.not-on-warp'} end + end, + open_on_join=true +} + +-- Event Handlers Define +script.on_event(defines.events.on_tick,function(event) + if not (event.tick % 60 == 0) then return end + for index,time in pairs(global.cooldowns) do + if time > 0 then + global.cooldowns[index] = time-1 + if global.cooldowns[index] == 0 then player_return({'WarpPoints.cooldown-zero'},defines.textcolor.low,index) end + end + end +end) + +script.on_event(defines.events.on_player_changed_position, function(event) + local player = Game.get_player(event) + local cooldown = global.cooldowns[player.index] or 0 + local tile = player.surface.get_tile(player.position).name + if not Role and player.admin or Role and not Role.allowed(player,'always-warp') and cooldown == 0 then + if tile == warp_tile and player.surface.name == 'nauvis' then + ThisModule.Gui:open(player) + elseif player.position.x^2+player.position.y^2 < (warp_radius*spawn_warp_scale)^2 then + ThisModule.Gui:open(player) + else ThisModule.Gui:close(player) end + end +end) + +script.on_event(defines.events.on_player_created, function(event) + if event.player_index == 1 then + local player = Game.get_player(event) + player.force.chart(player.surface, {{player.position.x - 20, player.position.y - 20}, {player.position.x + 20, player.position.y + 20}}) + local tag = player.force.add_chart_tag(player.surface,{ + position={0,0}, + text='Warp: Spawn', + icon={type='item',name=warp_item} + }) + global.warps['Spawn'] = {tag=tag,surface=player.surface.index,position={x=0,y=0}} + end +end) + +-- Module Return +return ThisModule \ No newline at end of file diff --git a/modules/WarpPoints/locale/de.cfg b/modules/WarpPoints/locale/de.cfg new file mode 100644 index 00000000..fac81895 --- /dev/null +++ b/modules/WarpPoints/locale/de.cfg @@ -0,0 +1,9 @@ +[WarpPoints] +name=Warp List +tooltip=Die Liste mit den Warp-Punkten +remove-tooltip=Entferne Warp-Punkt +go-to-tooltip=Gehe zu Warp-Punkt +cooldown=Warte, bis der Cooldown abgelaufen ist. Verbleibende Zeit: __1__ +cooldown-zero=Dein Cooldown ist abgelaufen, du kannst jetzt wieder Warp-Punkte verwenden. +name-used=Dieser Name ist schon vergeben. +not-on-warp=Du bist nicht auf einem Warp-Punkt. Gehe auf einen Warp-Punkt, um zu einem anderen zu springen. \ No newline at end of file diff --git a/modules/WarpPoints/locale/en.cfg b/modules/WarpPoints/locale/en.cfg new file mode 100644 index 00000000..0f517e6e --- /dev/null +++ b/modules/WarpPoints/locale/en.cfg @@ -0,0 +1,10 @@ +[WarpPoints] +name=Warp List +tooltip=A list of warp points. +remove-tooltip=Remove Warp point +go-to-tooltip=Go To +cooldown=You must wait for the cooldown. Time left: __1__ +cooldown-zero=Your cooldown has expired, You can use warp points again. +name-used=That name is already taken. +too-close=You are too close to an existing warp point to make a new one. +not-on-warp=You are not on a warp point right now, you must be on a warp point to go to one. \ No newline at end of file diff --git a/modules/WarpPoints/locale/fr.cfg b/modules/WarpPoints/locale/fr.cfg new file mode 100644 index 00000000..b15a3345 --- /dev/null +++ b/modules/WarpPoints/locale/fr.cfg @@ -0,0 +1,9 @@ +[WarpPoints] +name=Warp List +tooltip=A list of warp points. +remove-tooltip=Remove Warp Point +go-to-tooltip=Go To +cooldown=You Must Wait For The Cooldown, Time Left: __1__ +cooldown-zero=You Cooldown Has Expired, YOu Can Use Warp Points Again. +name-used=That Name Is Already Taken +not-on-warp=You Are Not On A Warp Point Right Now, You Must Be On A Warp Point To Go To One. \ No newline at end of file diff --git a/modules/WarpPoints/locale/nl.cfg b/modules/WarpPoints/locale/nl.cfg new file mode 100644 index 00000000..b15a3345 --- /dev/null +++ b/modules/WarpPoints/locale/nl.cfg @@ -0,0 +1,9 @@ +[WarpPoints] +name=Warp List +tooltip=A list of warp points. +remove-tooltip=Remove Warp Point +go-to-tooltip=Go To +cooldown=You Must Wait For The Cooldown, Time Left: __1__ +cooldown-zero=You Cooldown Has Expired, YOu Can Use Warp Points Again. +name-used=That Name Is Already Taken +not-on-warp=You Are Not On A Warp Point Right Now, You Must Be On A Warp Point To Go To One. \ No newline at end of file diff --git a/modules/WarpPoints/locale/sv-SE.cfg b/modules/WarpPoints/locale/sv-SE.cfg new file mode 100644 index 00000000..afbdb799 --- /dev/null +++ b/modules/WarpPoints/locale/sv-SE.cfg @@ -0,0 +1,9 @@ +[WarpPoints] +name=Warp-lista +tooltip=En lista över Warp-punkter. +remove-tooltip=Ta bort Warp-punkt +go-to-tooltip=Gå till +cooldown=Du måste vänta på nedräkningen. Tid kvar: __1__ +cooldown-zero=Din nedräkningstimer har gått ut, så nu kan du använda Warp-punkter igen. +name-used=Det namnet är redan taget. +not-on-warp=Du är inte på en Warp-punkt just nu, för att gå till en Warp-punkt måste du befinna dig på en. diff --git a/modules/WarpPoints/softmod.json b/modules/WarpPoints/softmod.json new file mode 100644 index 00000000..82df5531 --- /dev/null +++ b/modules/WarpPoints/softmod.json @@ -0,0 +1,22 @@ +{ + "name": "WarpPoints", + "version": "4.0.0", + "description": "Creates a warp point system which makes moving around large maps easier.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Warps", + "System", + "Teleport", + "PAX" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "ExpGamingCore.Role": "?^4.0.0", + "ExpGamingCore.Command": "?^4.0.0", + "ExpGamingCore.Gui": "^4.0.0" + }, + "submodules": {} +} diff --git a/modules/WarpPoints/src/commands.lua b/modules/WarpPoints/src/commands.lua new file mode 100644 index 00000000..9fe0e436 --- /dev/null +++ b/modules/WarpPoints/src/commands.lua @@ -0,0 +1,21 @@ +local warp_min_distance = warp_min_distance^2 +local warps = warps +local self = self + +commands.add_command('make-warp', 'Make a warp point at your location', { + ['name']={true,'string-inf'} +}, function(event,args) + if not game.player then return end + local position = game.player.position + local name = args.name + if name:len() > 40 then player_return({'ExpGamingCore_Command.error-string-len',40},defines.textcolor.med) return commands.error end + if game.player.gui.top[name] then player_return({'WarpPoints.name-used'},defines.textcolor.med) return commands.error end + if warps.warps[name] then player_return({'WarpPoints.name-used'},defines.textcolor.med) return commands.error end + for name,warp in pairs(warps.warps) do + local dx = position.x-warp.position.x + local dy = position.y-warp.position.y + if dx^2 + dy^2 < warp_min_distance then player_return({'WarpPoints.too-close'},defines.textcolor.med) return commands.error end + end + -- to do add a test for all warps + self.make_warp_point(position,game.player.surface,game.player.force,name) +end) \ No newline at end of file diff --git a/modules/WarpPoints/src/warp_entities.lua b/modules/WarpPoints/src/warp_entities.lua new file mode 100644 index 00000000..8944daf4 --- /dev/null +++ b/modules/WarpPoints/src/warp_entities.lua @@ -0,0 +1,5 @@ +return { + {'small-lamp',-3,-2},{'small-lamp',-3,2},{'small-lamp',3,-2},{'small-lamp',3,2}, + {'small-lamp',-2,-3},{'small-lamp',2,-3},{'small-lamp',-2,3},{'small-lamp',2,3}, + {'small-electric-pole',-3,-3},{'small-electric-pole',3,3},{'small-electric-pole',-3,3},{'small-electric-pole',3,-3} +} \ No newline at end of file diff --git a/modules/WarpPoints/src/warp_tiles.lua b/modules/WarpPoints/src/warp_tiles.lua new file mode 100644 index 00000000..01d7b6af --- /dev/null +++ b/modules/WarpPoints/src/warp_tiles.lua @@ -0,0 +1,4 @@ +return { + {-3,-2},{-3,-1},{-3,0},{-3,1},{-3,2},{3,-2},{3,-1},{3,0},{3,1},{3,2}, + {-2,-3},{-1,-3},{0,-3},{1,-3},{2,-3},{-2,3},{-1,3},{0,3},{1,3},{2,3} +} \ No newline at end of file diff --git a/modules/WornPaths/control.lua b/modules/WornPaths/control.lua new file mode 100644 index 00000000..1ccf1830 --- /dev/null +++ b/modules/WornPaths/control.lua @@ -0,0 +1,104 @@ +--- Makes paths which wear down and paths where entities are placed. +-- @module WornPaths@^4.0.0 +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE +-- @alias ThisModule + +-- Module Require +local Game = require('FactorioStdLib.Game') + +-- Local Variables +local entities = require(module_path..'/src/entites') +local paths = require(module_path..'/src/paths') +for _,value in pairs(paths) do value[1]=-1/value[1] end +local placed_paths = require(module_path..'/src/placed') + +local adjacency_boost = 2 -- makes paths more likely to be next to each other; must be greater than 0 +adjacency_boost = 10/adjacency_boost -- dont change this line + +-- Module Define +local module_verbose = false +local ThisModule = {} + +-- Global Define +local global = global() + +-- Function Define +local function global_key(surface,pos) + return 'S'..surface.name..'X'..math.floor(pos.x)..'Y'..math.floor(pos.y) +end + +--- Downgrades a tile in this position +-- @usage ThisModule.down_grade(surface,{x=10,y=10}) +-- @tparam surface surface the surface the tile is on +-- @tparam table pos the position of the tile to change +function ThisModule.down_grade(surface,pos) + local tile = surface.get_tile(pos).name + local new_tile = paths[tile][2] + if new_tile == 'world-gen' then + new_tile = global[global_key(surface,pos)] or 'grass-1' + end + surface.set_tiles{{name=new_tile,position=pos}} +end + +-- Event Handlers Define +script.on_event({defines.events.on_player_built_tile,defines.events.on_robot_built_tile}, function(event) + local surface = event.surface_index and game.surfaces[event.surface_index] or event.robot and event.robot.surface + local old_tiles = event.tiles + for _,old_tile in pairs(old_tiles) do + if not placed_paths[old_tile.old_tile.name] and old_tile.old_tile.name ~= 'water' and old_tile.old_tile.name ~= 'deepwater' then + global[global_key(surface,old_tile.position)]=old_tile.old_tile.name -- not a mistake, this makes it have demising returns + end + end +end) + +script.on_event(defines.events.on_player_changed_position, function(event) + local player = Game.get_player(event) + if not player or not player.valid or game.tick < 10 then return end + if player.afk_time > 300 then return end + local surface = player.surface + local pos = player.position + local tile_name = surface.get_tile(pos).name + if not paths[tile_name] then return end + local count = -9 -- this value is important + for x = -1,1 do for y = -1,1 do + local _pos = {pos.x+x,pos.y+y} + if placed_paths[tile_name] and not placed_paths[surface.get_tile(_pos).name] + or surface.get_tile(_pos).name == paths[tile_name][2] + then count=count+1 end + end end + local chance = paths[tile_name][1]/(count-adjacency_boost) + if math.random() < chance then + ThisModule.down_grade(surface,pos) + end +end) + +script.on_event({defines.events.on_built_entity,on_robot_built_entity}, function(event) + local entity = event.created_entity + local surface = entity.surface + if entities[entity.name] then + local box = entity.prototype.collision_box + for x = box.left_top.x,box.right_bottom.x do for y = box.left_top.y,box.right_bottom.y do + local pos = {x=entity.position.x+x,y=entity.position.y+y} + local tile = surface.get_tile(pos).name + if paths[tile] then ThisModule.down_grade(surface,pos) end + end end + end +end) +-- Module Return +-- when called it will downgrade a tile +return setmetatable(ThisModule,{__call=function(self,...) self.down_grade(...) end}) + +--[[ +/interface +local tile_name = surface.get_tile(position).name +if not paths[tile_name] then return end +local count = -9 -- this value is important +for x = -1,1 do for y = -1,1 do + local _pos = {position.x+x,position.y+y} + if placed_paths[tile_name] and not placed_paths[surface.get_tile(_pos).name] + or surface.get_tile(_pos).name == paths[tile_name][2] + then count=count+1 end +end end +return paths[tile_name][1]/(count-adjacency_boost) +]] \ No newline at end of file diff --git a/modules/WornPaths/softmod.json b/modules/WornPaths/softmod.json new file mode 100644 index 00000000..1b1a489a --- /dev/null +++ b/modules/WornPaths/softmod.json @@ -0,0 +1,19 @@ +{ + "name": "WornPaths", + "version": "4.0.0", + "description": "Makes paths which wear down and paths where entites are placed.", + "location": "FSM_ARCHIVE", + "keywords": [ + "Paths", + "Worn", + "Decay", + "Degrade" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "FactorioStdLib.Game": "^0.8.0" + }, + "submodules": {} +} diff --git a/modules/WornPaths/src/entites.lua b/modules/WornPaths/src/entites.lua new file mode 100644 index 00000000..6ee6868b --- /dev/null +++ b/modules/WornPaths/src/entites.lua @@ -0,0 +1,31 @@ +return { + ['stone-furnace']=true, + ['steel-furnace']=true, + ['electric-furnace']=true, + ['assembling-machine-1']=true, + ['assembling-machine-2']=true, + ['assembling-machine-3']=true, + ['beacon']=true, + ['centrifuge']=true, + ['chemical-plant']=true, + ['oil-refinery']=true, + ['storage-tank']=true, + ['nuclear-reactor']=true, + ['steam-engine']=true, + ['steam-turbine']=true, + ['boiler']=true, + ['heat-exchanger']=true, + ['stone-wall']=true, + ['gate']=true, + ['gun-turret']=true, + ['laser-turret']=true, + ['flamethrower-turret']=true, + ['radar']=true, + ['lab']=true, + ['big-electric-pole']=true, + ['substation']=true, + ['rocket-silo']=true, + ['pumpjack']=true, + ['electric-mining-drill']=true, + ['roboport']=true +} \ No newline at end of file diff --git a/modules/WornPaths/src/paths.lua b/modules/WornPaths/src/paths.lua new file mode 100644 index 00000000..a41a7dfc --- /dev/null +++ b/modules/WornPaths/src/paths.lua @@ -0,0 +1,27 @@ +return { + -- ['tile name'] = {health,convert to} + -- the greater health is the lower the chance it will be down graded, must be grater than 0 + ['refined-concrete']={70,'concrete'}, + ['refined-hazard-concrete-right']={70,'hazard-concrete-right'}, + ['refined-hazard-concrete-left']={70,'hazard-concrete-left'}, + ['concrete']={50,'stone-path'}, + ['hazard-concrete-right']={50,'stone-path'}, + ['hazard-concrete-left']={50,'stone-path'}, + ['stone-path']={40,'world-gen'}, -- world-gen just makes it pick the last tile not placed by a player + ['sand-1']={5,'sand-2'}, + ['sand-2']={10,'sand-3'}, + ['sand-3']={5,'red-desert-3'}, + ['red-desert-3']={5,'red-desert-2'}, + ['red-desert-2']={10,'dirt-1'}, + ['grass-2']={5,'grass-1'}, + ['grass-1']={5,'grass-3'}, + ['grass-3']={10,'red-desert-0'}, + ['red-desert-0']={5,'red-desert-1'}, + ['red-desert-1']={10,'dirt-1'}, + ['dirt-1']={5,'dirt-2'}, + ['dirt-2']={5,'dirt-3'}, + ['dirt-3']={10,'dirt-4'}, + ['dirt-4']={5,'dirt-5'}, + ['dirt-5']={5,'dirt-6'}, + ['grass-4']={10,'dirt-4'} +} \ No newline at end of file diff --git a/modules/WornPaths/src/placed.lua b/modules/WornPaths/src/placed.lua new file mode 100644 index 00000000..2fb909b1 --- /dev/null +++ b/modules/WornPaths/src/placed.lua @@ -0,0 +1,9 @@ +return { + ['refined-concrete']=true, + ['refined-hazard-concrete-right']=true, + ['refined-hazard-concrete-left']=true, + ['concrete']=true, + ['hazard-concrete-right']=true, + ['hazard-concrete-left']=true, + ['stone-path']=true +} \ No newline at end of file diff --git a/modules/index.lua b/modules/index.lua new file mode 100644 index 00000000..d48bd875 --- /dev/null +++ b/modules/index.lua @@ -0,0 +1,67 @@ +-- not_luadoc=true +--- Used to index the files to be loaded +return { + ['AdvancedStartingItems']={'./modules/AdvancedStartingItems',}, + ['ChatPopup']={'./modules/ChatPopup','FactorioStdLib.Game','FactorioStdLib.Color'}, + ['DamagePopup']={'./modules/DamagePopup','FactorioStdLib.Color'}, + ['DeathMarkers']={'./modules/DeathMarkers',}, + ['DeconControl']={'./modules/DeconControl','ExpGamingCore.Server','FactorioStdLib.Game','ExpGamingLib'}, + ['ExpGamingAdmin']={'./modules/ExpGamingAdmin','FactorioStdLib.Game'}, + ['ExpGamingBot']={'./modules/ExpGamingBot',}, + ['ExpGamingCommands']={'./modules/ExpGamingCommands',}, + ['ExpGamingCore']={'./modules/ExpGamingCore',}, + ['ExpGamingInfo']={'./modules/ExpGamingInfo',}, + ['ExpGamingLib']={'./modules/ExpGamingLib','FactorioStdLib.Game','FactorioStdLib.Color','FactorioStdLib.Table'}, + ['ExpGamingPlayer']={'./modules/ExpGamingPlayer',}, + ['FactorioStdLib']={'./modules/FactorioStdLib',}, + ['GameSettingsGui']={'./modules/GameSettingsGui','ExpGamingCore.Server','ExpGamingCore.Gui'}, + ['GuiAnnouncements']={'./modules/GuiAnnouncements','FactorioStdLib.Game','ExpGamingCore.Role','ExpGamingCore.Gui'}, + ['PlayerAutoColor']={'./modules/PlayerAutoColor','FactorioStdLib.Color'}, + ['SpawnArea']={'./modules/SpawnArea','FactorioStdLib.Game'}, + ['WarpPoints']={'./modules/WarpPoints','FactorioStdLib.Game','ExpGamingCore.Gui'}, + ['WornPaths']={'./modules/WornPaths','FactorioStdLib.Game'}, + ['ExpGamingAdmin.Gui']={'./modules/ExpGamingAdmin/Gui','ExpGamingAdmin.AdminLib','ExpGamingCore.Gui','ExpGamingCore.Role','FactorioStdLib.Game','mod-gui'}, + ['ExpGamingAdmin.Ban']={'./modules/ExpGamingAdmin/Ban','ExpGamingAdmin.AdminLib','ExpGamingAdmin.Gui','ExpGamingCore.Server','FactorioStdLib.Game'}, + ['ExpGamingAdmin.Reports']={'./modules/ExpGamingAdmin/Reports','ExpGamingAdmin.AdminLib','ExpGamingCore.Server','ExpGamingCore.Role','FactorioStdLib.Game','ExpGamingCore.Gui'}, + ['ExpGamingAdmin.ClearInventory']={'./modules/ExpGamingAdmin/ClearInventory','ExpGamingAdmin.AdminLib','FactorioStdLib.Game'}, + ['ExpGamingAdmin.TempBan']={'./modules/ExpGamingAdmin/TempBan','ExpGamingAdmin.AdminLib','ExpGamingCore.Server','ExpGamingCore.Role','FactorioStdLib.Game'}, + ['ExpGamingAdmin.Teleport']={'./modules/ExpGamingAdmin/Teleport','ExpGamingAdmin.AdminLib','ExpGamingAdmin.Gui','FactorioStdLib.Game'}, + ['ExpGamingAdmin.Commands']={'./modules/ExpGamingAdmin/Commands','ExpGamingLib','ExpGamingCore.Command','ExpGamingAdmin.AdminLib'}, + ['ExpGamingAdmin.Jail']={'./modules/ExpGamingAdmin/Jail','ExpGamingAdmin.AdminLib','ExpGamingAdmin.Gui','ExpGamingCore.Server','ExpGamingCore.Role','FactorioStdLib.Game'}, + ['ExpGamingAdmin.Warnings']={'./modules/ExpGamingAdmin/Warnings','ExpGamingAdmin.AdminLib','ExpGamingCore.Server','ExpGamingCore.Role','FactorioStdLib.Game'}, + ['ExpGamingAdmin.Kick']={'./modules/ExpGamingAdmin/Kick','ExpGamingAdmin.AdminLib','ExpGamingAdmin.Gui','ExpGamingCore.Server','FactorioStdLib.Game'}, + ['ExpGamingBot.autoMessage']={'./modules/ExpGamingBot/autoMessage','ExpGamingCore.Server','FactorioStdLib.Game'}, + ['ExpGamingBot.discordAlerts']={'./modules/ExpGamingBot/discordAlerts','ExpGamingCore.Sync','FactorioStdLib.Color','FactorioStdLib.Game'}, + ['ExpGamingBot.autoChat']={'./modules/ExpGamingBot/autoChat','FactorioStdLib.Game','ExpGamingCore.Server'}, + ['ExpGamingCommands.cheatMode']={'./modules/ExpGamingCommands/cheatMode','ExpGamingCore.Command'}, + ['ExpGamingCommands.repair']={'./modules/ExpGamingCommands/repair','ExpGamingLib','FactorioStdLib.Game','ExpGamingCore.Role'}, + ['ExpGamingCommands.tags']={'./modules/ExpGamingCommands/tags','ExpGamingLib','ExpGamingCore.Command','FactorioStdLib.Game'}, + ['ExpGamingCommands.home']={'./modules/ExpGamingCommands/home','FactorioStdLib.Game','ExpGamingCore.Command'}, + ['ExpGamingCore.Command']={'./modules/ExpGamingCore/Command','ExpGamingLib','FactorioStdLib.Table','FactorioStdLib.Color','FactorioStdLib.Game'}, + ['ExpGamingCommands.teleport']={'./modules/ExpGamingCommands/teleport','ExpGamingCore.Command','ExpGamingAdmin.Teleport','ExpGamingAdmin.AdminLib'}, + ['ExpGamingCommands.bonus']={'./modules/ExpGamingCommands/bonus','FactorioStdLib.Game','ExpGamingLib','ExpGamingCore.Command','ExpGamingCore.Role'}, + ['ExpGamingCommands.kill']={'./modules/ExpGamingCommands/kill','ExpGamingCore.Command','ExpGamingCore.Role','FactorioStdLib.Game'}, + ['ExpGamingCore.Server']={'./modules/ExpGamingCore/Server','ExpGamingLib','FactorioStdLib.Table','FactorioStdLib.Color','FactorioStdLib.String','FactorioStdLib.Game'}, + ['ExpGamingCore.Gui']={'./modules/ExpGamingCore/Gui','ExpGamingLib','FactorioStdLib.Table','FactorioStdLib.Color','FactorioStdLib.Game'}, + ['ExpGamingInfo.Science']={'./modules/ExpGamingInfo/Science','ExpGamingCore.Gui','FactorioStdLib.Game'}, + ['ExpGamingPlayer.playerList']={'./modules/ExpGamingPlayer/playerList','FactorioStdLib.Game','ExpGamingCore.Gui'}, + ['ExpGamingCore.Sync']={'./modules/ExpGamingCore/Sync','ExpGamingLib','FactorioStdLib.Color','FactorioStdLib.Game','FactorioStdLib.Table'}, + ['ExpGamingCore.Role']={'./modules/ExpGamingCore/Role','ExpGamingLib','FactorioStdLib.Table','FactorioStdLib.Game','ExpGamingCore.Group'}, + ['ExpGamingInfo.Readme']={'./modules/ExpGamingInfo/Readme','ExpGamingCore.Gui','FactorioStdLib.Game'}, + ['ExpGamingInfo.Rockets']={'./modules/ExpGamingInfo/Rockets','ExpGamingCore.Gui','FactorioStdLib.Game'}, + ['ExpGamingCore.Group']={'./modules/ExpGamingCore/Group','FactorioStdLib','ExpGamingLib','FactorioStdLib.Game'}, + ['ExpGamingInfo.Tasklist']={'./modules/ExpGamingInfo/Tasklist','ExpGamingCore.Gui','ExpGamingCore.Role','FactorioStdLib.Game'}, + ['ExpGamingPlayer.playerInfo']={'./modules/ExpGamingPlayer/playerInfo','FactorioStdLib.Game','ExpGamingCore.Gui'}, + ['ExpGamingPlayer.afkKick']={'./modules/ExpGamingPlayer/afkKick','FactorioStdLib.Game','ExpGamingCore.Gui'}, + ['FactorioStdLib.Table']={'./modules/FactorioStdLib/Table',}, + ['ExpGamingPlayer.polls']={'./modules/ExpGamingPlayer/polls','ExpGamingCore.Gui','ExpGamingCore.Server'}, + ['FactorioStdLib.Color']={'./modules/FactorioStdLib/Color',}, + ['FactorioStdLib.Game']={'./modules/FactorioStdLib/Game',}, + ['FactorioStdLib.String']={'./modules/FactorioStdLib/String',}, + ['ExpGamingPlayer.inventorySearch']={'./modules/ExpGamingPlayer/inventorySearch','ExpGamingLib','ExpGamingAdmin.TempBan','ExpGamingAdmin.Warnings','FactorioStdLib.Game','ExpGamingAdmin.AdminLib'}, + ['ExpGamingCore.Gui.center']={'./modules/ExpGamingCore/Gui/center','mod-gui','FactorioStdLib.Game','FactorioStdLib.Color','ExpGamingCore.Gui','ExpGamingCore.Gui.inputs'}, + ['ExpGamingCore.Gui.popup']={'./modules/ExpGamingCore/Gui/popup','mod-gui','FactorioStdLib.Game','ExpGamingCore.Gui','ExpGamingCore.Gui.inputs'}, + ['ExpGamingCore.Gui.toolbar']={'./modules/ExpGamingCore/Gui/toolbar','mod-gui','FactorioStdLib.Game','ExpGamingCore.Gui','ExpGamingCore.Gui.inputs'}, + ['ExpGamingCore.Gui.left']={'./modules/ExpGamingCore/Gui/left','mod-gui','FactorioStdLib.Game','ExpGamingCore.Server','FactorioStdLib.Color','ExpGamingCore.Gui','ExpGamingCore.Gui.inputs'}, + ['ExpGamingCore.Gui.inputs']={'./modules/ExpGamingCore/Gui/inputs','mod-gui','FactorioStdLib.Color','FactorioStdLib.Game','ExpGamingCore.Gui'}, +} \ No newline at end of file diff --git a/modules/softmod.json b/modules/softmod.json new file mode 100644 index 00000000..d74c2446 --- /dev/null +++ b/modules/softmod.json @@ -0,0 +1,33 @@ +{ + "name": "ExpGamingScenario", + "version": "4.0.0", + "description": "The basic scenario used on ExpGaming public servers", + "author": "ExpGaming", + "contact": "https://explosivegaming.nl", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "keywords": [ + "ExpGaming", + "Vanila Plus" + ], + "softmods": { + "AdvancedStartingItems": "4.0.0", + "ChatPopup": "4.0.0", + "DamagePopup": "4.0.0", + "DeathMarkers": "4.0.0", + "DeconControl": "4.0.0", + "ExpGamingAdmin": "4.0.0", + "ExpGamingBot": "4.0.0", + "ExpGamingCommands": "4.0.0", + "ExpGamingCore": "4.0.0", + "ExpGamingInfo": "4.0.0", + "ExpGamingLib": "4.0.0", + "ExpGamingPlayer": "4.0.0", + "FactorioStdLib": "0.8.0", + "GameSettingsGui": "4.0.0", + "GuiAnnouncements": "4.0.0", + "PlayerAutoColor": "4.0.0", + "SpawnArea": "4.0.0", + "WarpPoints": "4.0.0", + "WornPaths": "4.0.0" + } +}