From 35833f36ab13db2aa36cbb15aa9af46b82eed819 Mon Sep 17 00:00:00 2001 From: Tuulipommi Date: Wed, 19 Jun 2019 19:01:56 +0300 Subject: [PATCH 01/81] Update addons.cfg Fixed grammatical errors --- locale/en/addons.cfg | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index 444a8cbf..56cd4428 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -30,15 +30,15 @@ redmew=We dont talk about redmew here; they beat us to 1000 members ;-; lhd=All trains must be LHD! This is a long standing rule on our servers, please resepect this. [warnings] -received=You recived a warning from __1__. You have __2__ warnings. __3__ +received=You received a warning from __1__. You have __2__ warnings. __3__ pre-kick=This is your last warning before you are kicked. -kick=You were kicked for having too many warnings; you may rejoy if you wish. -pre-pre-ban=You are close to reciving a ban; successful ban appeals are unlikely. -pre-ban=This your LAST warning before you are BANNED! successful ban appeals are unlikely. -ban=You were banned for having too many warnings; Vist __1__ to request a ban appeal. -script-warning=You are reciving script warnings; if you recive too many you will recive a permiment warning (__1__/__2__) -script-wrning-removed=A script warning has expired (__1__/__2__) -script-warning-limit=__1__ has recived a permiment warning from the script. +kick=You were kicked for having too many warnings; you may rejoin if you wish. +pre-pre-ban=You are close to receiving a ban; successful ban appeals are unlikely. +pre-ban=This your LAST warning before you are BANNED! Successful ban appeals are unlikely. +ban=You were banned for having too many warnings; visit __1__ to request a ban appeal. +script-warning=You are receiving script warnings; if you recive too many you will receive a permanent warning (__1__/__2__) +script-warning-removed=A script warning has expired (__1__/__2__) +script-warning-limit=__1__ has received a permanent warning from the script. [chat-bot] reply=[Chat Bot] __1__ @@ -56,4 +56,4 @@ aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖ riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹‹\ (  ´)/››‹‹\ ( ´ω`)/›› (rest of server) loops=NO LOOPS; LOOPS ARE BAD; JUST NO LOOPS!!!!!; IF YOU MAKE A LOOP.... IT WILL NOT END WELL!!!!!!! lenny=( ͡° ͜ʖ ͡°) -hodor=Hodor \ No newline at end of file +hodor=Hodor From 4fe3d558e76135998a61a5b4d3954da04c2113b4 Mon Sep 17 00:00:00 2001 From: arty714 Date: Sat, 19 Oct 2019 17:09:17 +0200 Subject: [PATCH 02/81] Typos Corrected some typos. --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 93092fb6..affbc44a 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,13 @@ ## Explosive Gaming -Explosive Gaming (often ExpGaming) is a server hosting community with a strong focus on Factorio and games that follow similar ideas. Our factorio server are known for hosting large maps with the main goal of being a "mega base" which can produce as much as possible with in our reset schedule. Although these server tend to the more experienced players our server are open to everyone. You can find us through our [website], [discord], [wiki], or in the public games tab in factorio (ExpGaming S1). +Explosive Gaming (often ExpGaming) is a server hosting community with a strong focus on Factorio and games that follow similar ideas. Our Factorio server are known for hosting large maps with the main goal of being a "mega base" which can produce as much as possible within our reset schedule. Although these servers tend to attract the more experienced players, our servers are open to everyone. You can find us through our [website], [discord], [wiki], or in the public games tab in Factorio (ExpGaming S1, ExpGaming S2, etc.). ## Use and Installation 1) Download this [git repository](https://github.com/explosivegaming/scenario/archive/master.zip) for the stable release. The dev branch can be found [here](https://github.com/explosivegaming/scenario/archive/dev.zip) for those who want the latest features. See [releases](#releases) for other release branches. -2) Extract the downloaded zip file from the branch you downloaded into factorio's scenario directory: +2) Extract the downloaded zip file from the branch you downloaded into Factorio's scenario directory: * Windows: `%appdata%\Factorio\scenarios` * Linux: `~/.factorio/scenarios` @@ -38,13 +38,14 @@ Explosive Gaming (often ExpGaming) is a server hosting community with a strong f 4) More advanced users may want to play with the other configs files within `./config` but please be aware that some of the config files will require a basic understanding of lua while others may just be a list of values. -5) Once you have made any config changes that you wish to make open factorio, select play, then start scenario (or host scenario from within multiplayer tab), and select the scenario which will be called `scenario-master` if you have downloaded the latest stable release and have not changed the folder name. +5) Once you have made any config changes that you wish to make open Factorio, select play, then start scenario (or host scenario from within multiplayer tab), and select the scenario which will be called `scenario-master` if you have downloaded the latest stable release and have not changed the folder name. -6) The scenario will now load all the selected modules and start the map, any errors or exceptions raised in the scenario should not cause a game/server crash so if any features don't work as expected then it may be returning an error in the log, please report these errors to [the issues page](issues). +6) The scenario will now load all the selected modules and start the map, any errors or exceptions raised in the scenario should not cause a game/server crash, so if any features do not work as expected then it may be returning an error in the log. +Please report these errors to [the issues page](issues). ## Contributing -All are welcome to make pull requests and issues for this scenario, if you are in any doubt please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. All our docs can be found [here][docs]. Please keep in mind while making code changes: +All are welcome to make pull requests and issues for this scenario, if you are in any doubt, please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. All our docs can be found [here][docs]. Please keep in mind while making code changes: * New features should have the branch names: `feature/feature-name` * New features are merged into `dev` after it has been completed, this can be done through a pull request. From 886fb2c22690608fcead73eaea6e28c8a573ce1f Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 21 Oct 2019 22:17:59 +0100 Subject: [PATCH 03/81] Added main gui file --- config/_file_loader.lua | 15 +- docs/addons/Advanced-Start.html | 2 +- docs/addons/Chat-Popups.html | 2 +- docs/addons/Chat-Reply.html | 2 +- docs/addons/Compilatron.html | 2 +- docs/addons/Damage-Popups.html | 2 +- docs/addons/Death-Logger.html | 2 +- docs/addons/Discord-Alerts.html | 2 +- docs/addons/Player-Colours.html | 2 +- docs/addons/Pollution-Grading.html | 2 +- docs/addons/Scorched-Earth.html | 2 +- docs/addons/Spawn-Area.html | 2 +- docs/commands/Admin-Chat.html | 2 +- docs/commands/Bonus.html | 2 +- docs/commands/Cheat-Mode.html | 2 +- docs/commands/Clear-Inventory.html | 2 +- docs/commands/Debug.html | 2 +- docs/commands/Find.html | 2 +- docs/commands/Help.html | 2 +- docs/commands/Home.html | 2 +- docs/commands/Interface.html | 2 +- docs/commands/Jail.html | 2 +- docs/commands/Kill.html | 2 +- docs/commands/Me.html | 2 +- docs/commands/Rainbow.html | 2 +- docs/commands/Repair.html | 2 +- docs/commands/Reports.html | 2 +- docs/commands/Roles.html | 2 +- docs/commands/Spawn.html | 2 +- docs/commands/Tag.html | 2 +- docs/commands/Teleport.html | 2 +- docs/commands/Warnings.html | 2 +- docs/configs/Advanced-Start.html | 2 +- docs/configs/Bonuses.html | 2 +- docs/configs/Chat-Reply.html | 2 +- docs/configs/Commands-Auth-Admin.html | 2 +- docs/configs/Commands-Auth-Roles.html | 2 +- .../Commands-Auth-Runtime-Disable.html | 2 +- docs/configs/Commands-Parse-Roles.html | 2 +- docs/configs/Commands-Parse.html | 2 +- docs/configs/Compilatron.html | 2 +- docs/configs/Death-Logger.html | 2 +- docs/configs/Discord-Alerts.html | 2 +- docs/configs/File-Loader.html | 2 +- docs/configs/Permission-Groups.html | 2 +- docs/configs/Player-List.html | 2 +- docs/configs/Pollution-Grading.html | 2 +- docs/configs/Popup-Messages.html | 2 +- docs/configs/Preset-Player-Colours.html | 2 +- docs/configs/Repair.html | 2 +- docs/configs/Rockets.html | 2 +- docs/configs/Roles.html | 2 +- docs/configs/Science.html | 2 +- docs/configs/Scorched-Earth.html | 2 +- docs/configs/Spawn-Area.html | 2 +- docs/configs/Tasks.html | 2 +- docs/configs/Warnings.html | 2 +- docs/configs/Warps.html | 2 +- docs/control/Jail.html | 2 +- docs/control/Production.html | 2 +- docs/control/Reports.html | 2 +- docs/control/Rockets.html | 2 +- docs/control/Tasks.html | 2 +- docs/control/Warnings.html | 2 +- docs/control/Warps.html | 2 +- docs/core/Commands.html | 2 +- docs/core/Common-Library.html | 2 +- docs/core/Gui.html | 11143 ++-------------- docs/core/Permissions-Groups.html | 2 +- docs/core/Roles.html | 2 +- docs/core/Store.html | 2 +- docs/core/Sudo.html | 2 +- docs/guis/Player-List.html | 2 +- docs/guis/Rocket-Info.html | 2 +- docs/guis/Science-Info.html | 2 +- docs/guis/Task-List.html | 2 +- docs/guis/Warps-List.html | 2 +- docs/index.html | 7 +- docs/modules/control.html | 2 +- .../utils.alien_evolution_progress.html | 2 +- docs/modules/utils.core.html | 2 +- docs/modules/utils.debug.html | 2 +- docs/modules/utils.dump_env.html | 2 +- docs/modules/utils.event.html | 2 +- docs/modules/utils.event_core.html | 2 +- docs/modules/utils.math.html | 2 +- docs/modules/utils.recipe_locker.html | 2 +- docs/modules/utils.state_machine.html | 2 +- docs/modules/utils.table.html | 2 +- docs/modules/utils.task.html | 2 +- docs/modules/utils.timestamp.html | 2 +- docs/topics/license.html | 2 +- docs/topics/readme.md.html | 29 +- expcore/gui.lua | 659 +- expcore/gui/concepts/center.lua | 198 - expcore/gui/concepts/left.lua | 322 - expcore/gui/concepts/popups.lua | 230 - expcore/gui/concepts/toolbar.lua | 114 - expcore/gui/core.lua | 368 - expcore/gui/elements/buttons.lua | 128 - expcore/gui/elements/checkbox.lua | 247 - expcore/gui/elements/dropdown.lua | 184 - expcore/gui/elements/elem-button.lua | 96 - expcore/gui/elements/progress-bar.lua | 387 - expcore/gui/elements/slider.lua | 173 - expcore/gui/elements/text.lua | 145 - expcore/gui/instances.lua | 235 - expcore/gui/prototype.lua | 300 - expcore/gui/test.lua | 663 - 109 files changed, 1652 insertions(+), 14169 deletions(-) delete mode 100644 expcore/gui/concepts/center.lua delete mode 100644 expcore/gui/concepts/left.lua delete mode 100644 expcore/gui/concepts/popups.lua delete mode 100644 expcore/gui/concepts/toolbar.lua delete mode 100644 expcore/gui/core.lua delete mode 100644 expcore/gui/elements/buttons.lua delete mode 100644 expcore/gui/elements/checkbox.lua delete mode 100644 expcore/gui/elements/dropdown.lua delete mode 100644 expcore/gui/elements/elem-button.lua delete mode 100644 expcore/gui/elements/progress-bar.lua delete mode 100644 expcore/gui/elements/slider.lua delete mode 100644 expcore/gui/elements/text.lua delete mode 100644 expcore/gui/instances.lua delete mode 100644 expcore/gui/prototype.lua delete mode 100644 expcore/gui/test.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index c4a5bba6..44f73644 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -39,17 +39,18 @@ return { 'modules.addons.discord-alerts', 'modules.addons.chat-reply', -- GUI - 'modules.gui.rocket-info', - 'modules.gui.science-info', - 'modules.gui.warp-list', - 'modules.gui.task-list', - 'modules.gui.player-list', - 'modules.commands.debug', + --'modules.gui.rocket-info', + --'modules.gui.science-info', + --'modules.gui.warp-list', + --'modules.gui.task-list', + --'modules.gui.player-list', + --'modules.commands.debug', + 'expcore.gui', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.expcore-commands.auth_roles', -- commands must be allowed via the role config 'config.expcore-commands.auth_runtime_disable', -- allows commands to be enabled and disabled during runtime 'config.permission_groups', -- loads some predefined permission groups 'config.roles', -- loads some predefined roles - 'expcore.gui.test' -- loads multiple gui defines to test the gui system + --'expcore.gui.test' -- loads multiple gui defines to test the gui system } \ No newline at end of file diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index 8fc6a44a..4871b8c9 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -348,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index c9ea0f82..3efd7ce5 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index d6eda160..c5d3cfc4 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index 4fafcaa9..57a4a065 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index a445fe5a..f42f7dee 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index faadc765..6f540b7d 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index e0ecba4b..e9f689ac 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -460,7 +460,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index 8a60609c..06a8e29a 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index 46baddb7..806b86fd 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index c4f4487d..bcfab620 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 6b3002a3..7f9b0c0a 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 04b6b9fe..0a936c4e 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index 3786a596..e7e42cdd 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -500,7 +500,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index 81523c11..53b422c3 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -361,7 +361,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index a250f390..17ef4f9d 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index 0af8bb1c..880bb18e 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -365,7 +365,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index 0f1ae48d..f8d25958 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index 024c376f..b7d54d80 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index d4881527..d279fe65 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -458,7 +458,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index eeaf7d3d..8458181f 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 67d43bef..214140d6 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -611,7 +611,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index 967cb7e1..421f28a9 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index fbba050f..a31f9a45 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index f30d335d..439294a8 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index 361a22d7..98e6942b 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -321,7 +321,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index f94af164..1957df69 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index 3bc1f04d..0f9bc8b1 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -557,7 +557,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index 257da669..f72dbee2 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index 63606adc..60783e88 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -443,7 +443,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index 472651ba..353738fe 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -484,7 +484,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index a62c9b8e..d33d1547 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -569,7 +569,7 @@ generated by LDoc diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index 02b2965a..94b0896f 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -506,7 +506,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index 2e3966d2..e7bb072a 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index 727827bc..ee1e2dd2 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -485,7 +485,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index fd824730..157b0311 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -294,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index 4f49a827..59a9ed26 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index 9aacac5f..b299522c 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index 64d71e20..42155a89 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index 574f8aa4..8128d402 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -338,7 +338,7 @@ see ./expcore/commands.lua for more details

generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index 98043b31..0932f52e 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index 859cf7d9..1e635943 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index 4139d6e6..7214429c 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 8aa4661f..21a5ee90 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -240,7 +240,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index 305e744d..1ab7621e 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -295,7 +295,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index 2c9fc83f..bd67fe6b 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -812,7 +812,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index 64d7f6f0..d775b006 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index 114b8348..02436326 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index 824291f5..2d2a05a7 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -324,7 +324,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index e61920c5..5141d747 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index 929fbf4c..f011e724 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -834,7 +834,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index 5c7aabf3..e435071a 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -292,7 +292,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index c9c7fd1c..bea29f94 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index 3c038550..f271bf65 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index 4395fc07..a1a68698 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -744,7 +744,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index 1bd48171..e4f9760a 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index 78291b18..751529ef 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -355,7 +355,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index c8a87917..3840e9b9 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -684,7 +684,7 @@ generated by LDoc diff --git a/docs/control/Jail.html b/docs/control/Jail.html index 46633de1..8ed47a2e 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -1208,7 +1208,7 @@ generated by LDoc diff --git a/docs/control/Production.html b/docs/control/Production.html index ea5291cb..2cac6422 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -1329,7 +1329,7 @@ generated by LDoc diff --git a/docs/control/Reports.html b/docs/control/Reports.html index 4470dca7..16391654 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -1110,7 +1110,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index ea2c7aae..831e5343 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -984,7 +984,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index 41068882..c68201ec 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -998,7 +998,7 @@ Tasks.update_task(task_id,'We need more iron!',game. generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index abec17b0..ff7f7802 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -1465,7 +1465,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index ebb0dfb5..7791b32f 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -1563,7 +1563,7 @@ Warps.make_warp_tag(warp_id) generated by LDoc diff --git a/docs/core/Commands.html b/docs/core/Commands.html index 07dfce01..075e5bb8 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -1972,7 +1972,7 @@ generated by LDoc diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index 4206d114..caba804c 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -2746,7 +2746,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Gui.html b/docs/core/Gui.html index 09dee1fe..74601e95 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -42,21 +42,12 @@

Sections

@@ -217,21 +208,12 @@

Jump to Section

@@ -252,10 +234,7 @@

Gui core

Core Module - Gui - - This file is used to require all the different elements of the gui module - - each module has an outline here but for more details see their separate files in ./gui - - please read the files for more documentation that cant be shown here - - please note there is a rework planned but not started

+- Used to define new gui elements and gui event handlers

@@ -263,6 +242,42 @@ +

Usage

+
-- Defining a button that prints the player's name
+local example_button =
+Gui.new_element{
+    type = 'button',
+    caption = 'Example Button'
+}
+:on_click(function(event)
+    local player = event.player
+    player.print(player.name)
+end)
+
-- Defining using a custom function
+local example_flow_with_button =
+Gui.new_element(function(event_trigger,parent)
+    local flow =
+    parent.add{
+        name = 'example_flow',
+        type = 'flow'
+    }
+
+    local element =
+    flow.add{
+        name = event_trigger,
+        type = 'button',
+        caption = 'Example Button'
+    }
+
+    return element
+end)
+:on_click(function(event)
+    local player = event.player
+    player.print(player.name)
+end)
+
-- Drawing an element
+local exmple_button_element = example_button(parent)
+local example_flow_with_button = example_flow_with_button(parent)
@@ -275,840 +290,178 @@ - expcore.gui.core - - - expcore.gui.instances - - - expcore.gui.elements.buttons - - - expcore.gui.elements.checkbox - - - expcore.gui.elements.dropdown - - - expcore.gui.elements.slider - - - expcore.gui.elements.text - - - expcore.gui.elements.elem-button - - - expcore.gui.elements.progress-bar - - - expcore.gui.concepts.toolbar - - - expcore.gui.concepts.left - - - expcore.gui.concepts.center - - - expcore.gui.concepts.popups - - - - - -

Center Guis

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
expcore.gui.concepts.toolbar
utils.game
CenterFrames.get_flow(player)Gets the center flow for a player
CenterFrames.clear_flow(player)Clears the center flow for a player
CenterFrames.draw_frame(player, name)Draws the center frame for a player, if already open then will do nothing
CenterFrames.redraw_frame(player, name)Draws the center frame for a player, if already open then will destroy it and redraw
CenterFrames.toggle_frame(player, name[, state])Toggles if the frame is currently open or not, will open if closed and close if open
CenterFrames.new_frame(permission_name)Creates a new center frame define
CenterFrames._prototype:set_auto_focus([state=true])Sets the frame to be the current active gui when opened and closes all other frames
CenterFrames._prototype:draw_frame(player)Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame)
CenterFrames._prototype:redraw_frame(player)Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame)
CenterFrames._prototype:toggle_frame(player)Toggles if the frame is open, if open it will close it and if closed it will open it
CenterFrames._prototype:event_handler([action=update])Creates an event handler that will trigger one of its functions, use with Event.add
- - -

Left Guis

- - - - - - - - - - - - - - + + +
expcore.gui.core
expcore.gui.prototype
expcore.gui.concepts.toolbar
expcore.gui.elements.buttonsutils.event
mod-gui
+ + +

Tables

+ + + - + + - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
utils.gametop_elementsContains the uids of the elements that will show on the top flow and the auth function
utils.eventleft_elementsContains the uids of the elements that will show on the left flow and the open on join function
LeftFrames.get_flow(player)Gets the left frame flow for a playerdefinesTable of all the elements which have been registed with the draw function and event handlers
LeftFrames.get_frame(name, player)Gets one frame from the left flow by its namefile_pathsAn index used for debuging to find the file where different elements where registered
LeftFrames.get_open(player)Gets all open frames for a player, if non are open it will remove the close all button_prototype_elementThe element prototype which is returned from Gui.new_element
LeftFrames.toggle_frame(name, player[, state])Toggles the visibility of a left frame, or sets its visibility state
LeftFrames.new_frame(permission_name)Creates a new left frame define
LeftFrames._prototype:set_open_by_default([state=true])Sets if the frame is visible when a player joins, can also be a function to return a boolean
LeftFrames._prototype:set_direction(direction)Sets the direction of the frame, either vertical or horizontal
LeftFrames._prototype:_internal_draw(player)Creates the gui for the first time, used internally
LeftFrames._prototype:get_frame(player)Gets the frame for this define from the left frame flow
LeftFrames._prototype:is_open(player)Returns if the player currently has this define visible
LeftFrames._prototype:toggle(player)Toggles the visibility of the left frame
LeftFrames._prototype:update(player)Updates the contents of the left frame, first tries update callback, other wise will clear and redraw
LeftFrames._prototype:update_all([update_offline=false])Updates the frame for all players, see update
LeftFrames._prototype:redraw(player)Redraws the frame by calling on_draw, will always clear the frame
LeftFrames._prototype:redraw_all([update_offline=false])Redraws the frame for all players, see redraw
LeftFrames._prototype:event_handler([action=update])Creates an event handler that will trigger one of its functions, use with Event.add_mt_elementThe prototype metatable applied to new element defines
-

Popups

+

Fields

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
expcore.gui.core
expcore.gui.prototype
utils.game
utils.event
expcore.gui.elements.progress-bar
expcore.gui.elements.buttons
mod-gui
resources.color_presets
utils.global
PopupFrames.get_flow(player)Gets the left flow that contains the popup frames
PopupFrames.open(define_name, player[, open_time], ...)Opens a popup for the player, can give the amount of time it is open as well as params for the draw function
PopupFrames.close_progressProgress bar which when depleted will close the popup frame
PopupFrames.close_buttonA button which can be used to close the gui before the timer runs out
PopupFrames.new_popup([name])Creates a new popup frame define
PopupFrames._prototype:set_default_open_time(amount)Sets the default open time for the popup, will be used if non is provided with open
PopupFrames._prototype:open(player[, open_time], ...)Opens this define for a player, can be given open time and any other params for the draw functionuidThe current highest uid that is being used, will not increase during runtime
-

Toolbar

+

Element Define

- + + - + + - - - - - - - - - - - - - - - - - - - - - - + +
expcore.gui.corenew_element(element_define)Base function used to define new elements, can be used with a table or with a function
expcore.gui.elements.buttonsGui._prototype_element:add_to_top_flow([authenticator])Adds an element to be drawn to the top flow when a player joins
expcore.roles
utils.event
utils.game
mod-gui
Toolbar.new_button([name])Adds a new button to the toolbar
Toolbar.add_button(button)Adds an existing buttton to the toolbar
Toolbar.update(player)Updates the player's toolbar with an new buttons or expected change in auth returnGui._prototype_element:add_to_left_flow([open_on_join])Adds an element to be drawn to the left flow when a player joins
-

Core

+

Element Events

- + + - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - + +
utils.guiGui._prototype_element.on_openedCalled when the player opens a GUI.
utils.gameGui._prototype_element.on_closedCalled when the player closes the GUI they have open.
new_define(prototype[, debug_name])Used to create new element defines from a class prototype, please use the own given by the classGui._prototype_element.on_clickCalled when LuaGuiElement is clicked.
get_define(name[, internal])Gets an element define give the uid, debug name or a copy of the element defineGui._prototype_element.on_confirmedCalled when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.
categorize_by_player(element)A categorize function to be used with add_store, each player has their own valueGui._prototype_element.on_checked_changedCalled when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).
categorize_by_force(element)A categorize function to be used with add_store, each force has its own valueGui._prototype_element.on_elem_changedCalled when LuaGuiElement element value is changed (related to choose element buttons).
categorize_by_surface(element)A categorize function to be used with add_store, each surface has its own valueGui._prototype_element.on_location_changedCalled when LuaGuiElement element location is changed (related to frames in player.gui.screen).
draw(name, element)Draws a copy of the element define to the parent element, see draw_toGui._prototype_element.on_tab_changedCalled when LuaGuiElement selected tab is changed (related to tabbed-panes).
toggle_enabled(element)Will toggle the enabled state of an elementGui._prototype_element.on_selection_changedCalled when LuaGuiElement selection state is changed (related to drop-downs and listboxes).
toggle_visible(element)Will toggle the visiblity of an elementGui._prototype_element.on_switch_changedCalled when LuaGuiElement switch state is changed (related to switches).
set_padding(element[, up=0][, down=0][, left=0][, right=0])Sets the padding for a gui elementGui._prototype_element.on_text_changeCalled when LuaGuiElement text is changed by the player.
set_padding_style(style[, up=0][, down=0][, left=0][, right=0])Sets the padding for a gui style
create_alignment(element[, name][, horizontal_align='right'][, vertical_align='center'])Allows the creation of an alignment flow to place elements into
destroy_if_valid(element)Destroies an element but tests for it being present and valid first
create_scroll_table(element, table_size, maximal_height[, name='scroll'])Creates a scroll area with a table inside, table can be any size
create_header(element, caption[, tooltip][, right_align][, name='header'])Creates a header section with a label and button areaGui._prototype_element.on_value_changedCalled when LuaGuiElement slider value is changed (related to the slider element).
-

Buttons

+

Top Flow

- + + - + + - + + - - - - - - - - - - - - - - + +
mod-guitoggle_top_flowButton which toggles the top flow elements
expcore.gui.coreget_top_flow(player)Gets the flow which contains the elements for the top flow
expcore.gui.prototypeupdate_top_flow(player)Updates the visible states of all the elements on a players top flow
Button.new_button([name])Creates a new button element define
Button._prototype:set_sprites(sprite[, hovered_sprite][, clicked_sprite])Adds sprites to a button making it a sprite button
Button._prototype:set_click_filter(filter[, ...])Adds a click / mouse button filter to the button
Button._prototype:set_key_filter(filter[, ...])Adds a control key filter to the buttontoggle_top_flow(player[, state])Toggles the visible states of all the elements on a players top flow
-

Checkboxs

+

Left Flow

- + + - + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.corehide_left_flowButton which hides the elements in the left flow
expcore.gui.prototypeget_left_flow(player)Gets the flow which contains the elements for the left flow
expcore.storehide_left_flow(player)Hides all left elements for a player
utils.game
Checkbox.new_checkbox([name])Creates a new checkbox element define
Checkbox.new_radiobutton([name])Creates a new radiobutton element define, has all functions checkbox has
Checkbox._prototype_radiobutton:add_as_option(option_set, option_name)Adds this radiobutton to be an option in the given option set (only one can be true at a time)
Checkbox._prototype_radiobutton:get_store(category, internal)Gets the stored value of the radiobutton or the option set if present
Checkbox._prototype_radiobutton:set_store(category, value, internal)Sets the stored value of the radiobutton or the option set if present
Checkbox.new_option_set(callback, categorize)Registers a new option set that can be linked to radiobuttons (only one can be true at a time)
Checkbox.draw_option_set(name, element)Draws all radiobuttons that are part of an option set at once (Gui.draw will not work)
Checkbox.reset_radiobuttons(element[, exclude][, recursive=false])Sets all radiobutton in a element to false (unless excluded) and can act recursively
- - -

Dropdowns

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
utils.game
Dropdown.new_dropdown([name])Creates a new dropdown element define
Dropdown.new_list_box([name])Creates a new list box element define
Dropdown._prototype:new_static_options(options[, ...], the)Adds new static options to the dropdown which will trigger the general callback
Dropdown._prototype:new_dynamic_options(callback)Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options)
Dropdown._prototype:add_option_callback(option, callback)Adds a case specific callback which will only run when that option is selected (general case still triggered)
Dropdown.select_value(element, value)Selects the option from a dropdown or list box given the value rather than key
Dropdown.get_selected_value(element)Returns the currently selected value rather than index
- - -

Elem Buttons

- - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
utils.game
ElemButton.new_elem_button([name])Creates a new elem button element define
ElemButton._prototype.set_typeSets the type of the elem button, the type is required so this must be called at least once
ElemButton._prototype:set_default(value)Sets the default value for the elem button, this may be a function or a string
- - -

Progress Bars

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
utils.global
utils.game
ProgressBar.set_maximum(element, amount)Sets the maximum value that represents the end value of the progress bar
ProgressBar.increment(element[, amount=1])Increases the value of the progressbar, if a define is given all of its instances have incremented
ProgressBar.decrement(element[, amount=1])Decreases the value of the progressbar, if a define is given all of its instances have decremented
ProgressBar.new_progressbar([name])Creates a new progressbar element define
ProgressBar._prototype:set_default_maximum(amount)Sets the maximum value that represents the end value of the progress bar
ProgressBar._prototype:use_count_down([state=true])Will set the progress bar to start at 1 and trigger when it hits 0
ProgressBar._prototype:increment([amount=1][, category])Increases the value of the progressbar
ProgressBar._prototype:increment_filtered([amount=1], filter)Increases the value of the progressbar, if the filter condition is met, does not work with store
ProgressBar._prototype:decrement([amount=1][, category])Decreases the value of the progressbar
ProgressBar._prototype:decrement_filtered([amount=1], filter)Decreases the value of the progressbar, if the filter condition is met, does not work with store
ProgressBar._prototype:add_element(element[, maximum])Adds an element into the list of instances that will are waiting to complete, does not work with store - note use store if you want persistent data, this only stores the elements not the values which they have
ProgressBar._prototype:reset_element(element)Resets an element, or its store, to be back at the start, either 1 or 0
ProgressBar._prototype:event_counter([filter])Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented
ProgressBar._prototype:event_countdown([filter])Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented
- - -

Sliders

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
expcore.gui.instances
utils.game
Slider.new_slider([name])Creates a new slider element define
Slider._prototype:set_range([min][, max])Sets the range of a slider, if not used will use default values for a slider
Slider._prototype:draw_label(element)Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player
Slider._prototype:enable_auto_draw_label([state=true])Enables auto draw of the label, the label will share the same parent element as the slider
- - -

Text

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
expcore.gui.core
expcore.gui.prototype
utils.game
Text.new_text_field([name])Creates a new text field element define
Text.new_text_box([name])Creates a new text box element define
Text._prototype_box:set_selectable([state=true])Sets the text box to be selectable
Text._prototype_box:set_word_wrap([state=true])Sets the text box to have word wrap
Text._prototype_box:set_read_only([state=true])Sets the text box to be read only
- - -

Instances

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
utils.global
Instances.has_categories(name)Returns if a instance group has a serializer function; must be registered
Instances.is_registered(name)Returns if the given name is a registered instance group
Instances.register(name[, serializer])Registers the name of an instance group to allow for storing element instances
Instances.add_element(name, element)Adds an element to the instance group under the correct category; must be registered
Instances.get_elements_raw(name[, category])Gets all element instances without first removing any invalid ones; used internally and must be registered
Instances.get_valid_elements(name[, category][, callback])Gets all valid element instances and has the option of running a callback on those that are valid
Instances.unregistered_add_element(name, category, element)A version of add_element that does not require the group to be registered
Instances.unregistered_get_elements(name, category[, callback])A version of get_elements that does not require the group to be registered
- - -

Prototype

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
utils.game
expcore.store
expcore.gui.instances
Constructor.event(event_name)Creates a new function to add functions to an event handler
Constructor.extend(new_prototype)Extents a prototype with the base functions of all gui prototypes, no metatables
Constructor.store(callback)Creates a new function which adds a store to a gui define
Constructor.setter(value_type, key[, second_key])Creates a setter function that checks the type when a value is set
Prototype:uid()Gets the uid for the element define
Prototype.debug_nameSets a debug alias for the define
Prototype.set_captionSets the caption for the element define
Prototype.set_tooltipSets the tooltip for the element define
Prototype.set_pre_authenticatorSets an authenticator that blocks the draw function if check fails
Prototype.set_post_authenticatorSets an authenticator that disables the element if check fails
Prototype.on_drawRegisters a callback to the on_draw event
Prototype.on_style_updateRegisters a callback to the on_style_update event
Prototype:set_style(style[, callback])Sets the style for the element define
Prototype:set_embedded_flow(state)Sets the element to be drawn inside a nameless flow, can be given a name using a function
Prototype:raise_event(event_name, ...)Raises a custom event for this define, any number of params can be given
Prototype:draw_to(element)The main function for defines, when called will draw an instance of this define to the given element - what is drawn is based on the data in draw_data which is set using other functions
Prototype:get_store(category)Gets the value in this elements store, category needed if serializer function used
Prototype:set_store(category, value)Sets the value in this elements store, category needed if serializer function used
Prototype:clear_store([category])Sets the value in this elements store to nil, category needed if serializer function used
- - -

Test

- - - - - - - - - - - - - - - - - + +
expcore.gui
expcore.common
resources.color_presets
utils.event
expcore.storetoggle_left_element(player, element_define[, state])Toggles the visible state of all a left element for a player
@@ -1122,1187 +475,8 @@
- # - expcore.gui.core -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.instances -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.buttons -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.checkbox -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.dropdown -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.slider -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.text -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.elem-button -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.progress-bar -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.toolbar -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.left -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.center -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.popups -
-
-
-
- - - - - - - - - - - - - - - -
- -

Center Guis

-
-
-
-
- # - expcore.gui.core -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.prototype -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.toolbar -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - utils.game -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - CenterFrames.get_flow(player) -
-
-
-
- -

Gets the center flow for a player

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to get the flow for - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames.clear_flow(player) -
-
-
-
- -

Clears the center flow for a player

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to clear the flow for - -
  • - - -
- - - - - - - - - - - - - -
-
-
-
- # - CenterFrames.draw_frame(player, name) -
-
-
-
- -

Draws the center frame for a player, if already open then will do nothing

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player that will have the frame drawn - -
  • - - - - - -
  • - - name - - : - - (string) - - the name of the hui that will drawn - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames.redraw_frame(player, name) -
-
-
-
- -

Draws the center frame for a player, if already open then will destroy it and redraw

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player that will have the frame drawn - -
  • - - - - - -
  • - - name - - : - - (string) - - the name of the hui that will drawn - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames.toggle_frame(player, name[, state]) -
-
-
-
- -

Toggles if the frame is currently open or not, will open if closed and close if open

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player that will have the frame toggled - -
  • - - - - - -
  • - - name - - : - - (string) - - the name of the hui that will be toggled - -
  • - - - - - -
  • - - state - - : - - (boolean) - - when set will force a state for the frame - - (optional) -
  • - - -
- - - - - Returns: -
    -
  • - (boolean) - if the frame if no open or closed -
  • -
- - - - - - - - - -
-
-
-
- # - CenterFrames.new_frame(permission_name) -
-
-
-
- -

Creates a new center frame define

-

- - - Parameters: - -
    - - - - - -
  • - - permission_name - - : - - (string) - - the name that can be used with the permission system - -
  • - - -
- - - - - Returns: -
    -
  • - (table) - the new center frame define -
  • -
- - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:set_auto_focus([state=true]) -
-
-
-
- -

Sets the frame to be the current active gui when opened and closes all other frames

-

- - - Parameters: - -
    - - - - - -
  • - - state - - : - - (boolean) - - when true will auto close other frames and set this frame as player.opened - - (default: true) -
  • - - -
- - - - - - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:draw_frame(player) -
-
-
-
- -

Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame)

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to draw the frame for - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:redraw_frame(player) -
-
-
-
- -

Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame)

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to draw the frame for - -
  • - - -
- - - - - Returns: - - - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:toggle_frame(player) -
-
-
-
- -

Toggles if the frame is open, if open it will close it and if closed it will open it

-

- - - Parameters: - -
    - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to draw the frame for - -
  • - - -
- - - - - Returns: -
    -
  • - (boolean) - with the gui frame is now open -
  • -
- - - - - - - - - -
-
-
-
- # - CenterFrames._prototype:event_handler([action=update]) -
-
-
-
- -

Creates an event handler that will trigger one of its functions, use with Event.add

-

- - - Parameters: - -
    - - - - - -
  • - - action - - : - - (string) - - the action to take on this event - - (default: update) -
  • - - -
- - - - - - - - - - - - - -
-
-

Left Guis

-
-
-
-
- # - expcore.gui.core -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.prototype -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.concepts.toolbar -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
- # - expcore.gui.elements.buttons + # + utils.event
@@ -2348,16 +522,21 @@
+
+

Tables

+
- # - utils.game + # + top_elements
+

Contains the uids of the elements that will show on the top flow and the auth function

+

@@ -2376,13 +555,15 @@
- # - utils.event + # + left_elements
+

Contains the uids of the elements that will show on the left flow and the open on join function

+

@@ -2401,14 +582,196 @@
- # - LeftFrames.get_flow(player) + # + defines
-

Gets the left frame flow for a player

+

Table of all the elements which have been registed with the draw function and event handlers

+

+ + + + + + + + + + + + + + +
+
+
+
+ # + file_paths +
+
+
+
+ +

An index used for debuging to find the file where different elements where registered

+

+ + + + + + + + + + + + + + +
+
+
+
+ # + _prototype_element +
+
+
+
+ +

The element prototype which is returned from Gui.new_element

+

+ + + + + + + + + + + + + + +
+
+
+
+ # + _mt_element +
+
+
+
+ +

The prototype metatable applied to new element defines

+

+ + + Fields: + +
    + + + + + +
  • + + __call + + + + + +
  • + + +
+ + + + + + + + + + + + + +
+
+

Fields

+
+
+
+
+ # + uid +
+
+
+
+ +

The current highest uid that is being used, will not increase during runtime

+

+ + + +
    + + + + + +
  • + + uid + + + + + +
  • + + +
+ + + + + + + + + + + + + +
+
+

Element Define

+
+
+
+
+ # + new_element(element_define) +
+
+
+
+ +

Base function used to define new elements, can be used with a table or with a function

@@ -2422,143 +785,13 @@
  • - player + element_define : - (LuaPlayer) + (table or function) - the player to get the flow of - -
  • - - - - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames.get_frame(name, player) -
    -
    -
    -
    - -

    Gets one frame from the left flow by its name

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the gui frame to get - -
    • - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the frame of - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the frame in the left frame flow with that name -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames.get_open(player) -
    -
    -
    -
    - -

    Gets all open frames for a player, if non are open it will remove the close all button

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the flow of + used to define how the element is draw, using a table is the simplist way of doing this
    • @@ -2572,7 +805,7 @@
      • (table) - contains all the open (and registered) frames for the player + the new element define that is used to register events to this element
      @@ -2582,20 +815,45 @@ + Usage: +
      -- Defining an element with a table
      +local example_button =
      +Gui.new_element{
      +    type = 'button',
      +    caption = 'Example Button'
      +}
      +
      -- Defining an element with a function
      +local example_flow_with_button =
      +Gui.new_element(function(event_trigger,parent)
      +    local flow =
      +    parent.add{
      +        name = 'example_flow',
      +        type = 'flow'
      +    }
      +
      +    local element =
      +    flow.add{
      +        name = event_trigger,
      +        type = 'button',
      +        caption = 'Example Button'
      +    }
      +
      +    return element
      +end)
    - # - LeftFrames.toggle_frame(name, player[, state]) + # + Gui._prototype_element:add_to_top_flow([authenticator])
    -

    Toggles the visibility of a left frame, or sets its visibility state

    +

    Adds an element to be drawn to the top flow when a player joins

    @@ -2609,45 +867,13 @@
  • - name + authenticator : - (string) + (function) - the name of the gui frame to toggle - -
  • - - - - - -
  • - - player - - : - - (LuaPlayer) - - the player to get the frame of - -
  • - - - - - -
  • - - state - - : - - (boolean) - - when given will be the state that the visibility is set to + called during toggle or update to decide if the element should be visible (optional)
  • @@ -2658,13 +884,6 @@ - Returns: -
      -
    • - (boolean) - the new state of the visibility -
    • -
    @@ -2672,20 +891,26 @@ + Usage: +
    -- Adding the example button
    +example_button:add_to_top_flow(function(player)
    +    -- example button will only show when game time is less than 1 minute
    +    return player.online_time < 3600
    +end)
    - # - LeftFrames.new_frame(permission_name) + # + Gui._prototype_element:add_to_left_flow([open_on_join])
    -

    Creates a new left frame define

    +

    Adds an element to be drawn to the left flow when a player joins

    @@ -2699,606 +924,15 @@
  • - permission_name - - : - - (string) - - the name that can be used with the permission system - -
  • - - - - - - - - Returns: -
      -
    • - (table) - the new left frame define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:set_open_by_default([state=true]) -
    -
    -
    -
    - -

    Sets if the frame is visible when a player joins, can also be a function to return a boolean

    -

    - - - Parameters: - -
      - - - - - -
    • - - state + open_on_join : (boolean or function) - the default state of the visibility, can be a function - state param - player LuaPlayer - the player that has joined the game - state param - define_name string - the define name for the frame - state return - boolean - false will hide the frame + called during first darw to decide if the element is visible - (default: true) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:set_direction(direction) -
    -
    -
    -
    - -

    Sets the direction of the frame, either vertical or horizontal

    -

    - - - Parameters: - -
      - - - - - -
    • - - direction - - : - - (string) - - the direction to have the elements be added to the frame - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:_internal_draw(player) -
    -
    -
    -
    - -

    Creates the gui for the first time, used internally

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to draw the frame to - -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:get_frame(player) -
    -
    -
    -
    - -

    Gets the frame for this define from the left frame flow

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the frame of - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the frame in the left frame flow for this define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:is_open(player) -
    -
    -
    -
    - -

    Returns if the player currently has this define visible

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the frame of - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if it is open/visible -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:toggle(player) -
    -
    -
    -
    - -

    Toggles the visibility of the left frame

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to toggle the frame of - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - the new state of the visibility -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:update(player) -
    -
    -
    -
    - -

    Updates the contents of the left frame, first tries update callback, other wise will clear and redraw

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to update the frame of - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:update_all([update_offline=false]) -
    -
    -
    -
    - -

    Updates the frame for all players, see update

    -

    - - - Parameters: - -
      - - - - - -
    • - - update_offline - - : - - (boolean) - - when true will update the frame for offline players - - (default: false) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:redraw(player) -
    -
    -
    -
    - -

    Redraws the frame by calling on_draw, will always clear the frame

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to update the frame of - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:redraw_all([update_offline=false]) -
    -
    -
    -
    - -

    Redraws the frame for all players, see redraw

    -

    - - - Parameters: - -
      - - - - - -
    • - - update_offline - - : - - (boolean) - - when true will update the frame for offline players - - (default: false) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - LeftFrames._prototype:event_handler([action=update]) -
    -
    -
    -
    - -

    Creates an event handler that will trigger one of its functions, use with Event.add

    -

    - - - Parameters: - -
      - - - - - -
    • - - action - - : - - (string) - - the action to take on this event - - (default: update) + (optional)
    • @@ -3314,3911 +948,26 @@ + Usage: +
      -- Adding the example button
      +example_flow_with_button:add_to_left_flow(true)
    -

    Popups

    +

    Element Events

    - # - expcore.gui.core + # + Gui._prototype_element.on_opened
    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.event -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.elements.progress-bar -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.elements.buttons -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - mod-gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - resources.color_presets -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.global -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.get_flow(player) -
    -
    -
    -
    - -

    Gets the left flow that contains the popup frames

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to get the flow for - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the left flow that contains the popup frames -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.open(define_name, player[, open_time], ...) -
    -
    -
    -
    - -

    Opens a popup for the player, can give the amount of time it is open as well as params for the draw function

    -

    - - - Parameters: - -
      - - - - - -
    • - - define_name - - : - - (string) - - the name of the define that you want to open for the player - -
    • - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to open the popup for - -
    • - - - - - -
    • - - open_time - - : - - (number) - - the minimum number of ticks you want the popup open for, 0 means no limit, nil will take default - - (optional) -
    • - - - - - -
    • - - ... - - : - - (any) - - the other params that you want to pass to your on_draw event - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the frame that was drawn, the inner gui flow which contains the content -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.close_progress -
    -
    -
    -
    - -

    Progress bar which when depleted will close the popup frame

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.close_button -
    -
    -
    -
    - -

    A button which can be used to close the gui before the timer runs out

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames.new_popup([name]) -
    -
    -
    -
    - -

    Creates a new popup frame define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new popup frame define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames._prototype:set_default_open_time(amount) -
    -
    -
    -
    - -

    Sets the default open time for the popup, will be used if non is provided with open

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the number of ticks, by default, the popup will be open for - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the define to allow for chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - PopupFrames._prototype:open(player[, open_time], ...) -
    -
    -
    -
    - -

    Opens this define for a player, can be given open time and any other params for the draw function

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to open the popup for - -
    • - - - - - -
    • - - open_time - - : - - (number) - - the minimum number of ticks you want the popup open for, 0 means no limit, nil will take default - - (optional) -
    • - - - - - -
    • - - ... - - : - - (any) - - the other params that you want to pass to your on_draw event - -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the frame that was drawn, the inner gui flow which contains the content -
    • -
    - - - - - - - - - -
    -
    -

    Toolbar

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.elements.buttons -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.roles -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.event -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - mod-gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Toolbar.new_button([name]) -
    -
    -
    -
    - -

    Adds a new button to the toolbar

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - when given allows an alias to the button for the permission system - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the button define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Toolbar.add_button(button) -
    -
    -
    -
    - -

    Adds an existing buttton to the toolbar

    -

    - - - Parameters: - -
      - - - - - -
    • - - button - - : - - (table) - - the button define for the button to be added - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Toolbar.update(player) -
    -
    -
    -
    - -

    Updates the player's toolbar with an new buttons or expected change in auth return

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to update the toolbar for - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -

    Core

    -
    -
    -
    -
    - # - utils.gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - new_define(prototype[, debug_name]) -
    -
    -
    -
    - -

    Used to create new element defines from a class prototype, please use the own given by the class

    -

    - - - Parameters: - -
      - - - - - -
    • - - prototype - - : - - (table) - - the class prototype that will be used for the element define - -
    • - - - - - -
    • - - debug_name - - : - - (string) - - the name that you want to see while debuging - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new element define with all functions accessed via __index metamethod -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - get_define(name[, internal]) -
    -
    -
    -
    - -

    Gets an element define give the uid, debug name or a copy of the element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string or table) - - the uid, debug name or define for the element define to get - -
    • - - - - - -
    • - - internal - - : - - (boolean) - - when true the error trace is one level higher (used internally) - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the element define that was found or an error -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - categorize_by_player(element) -
    -
    -
    -
    - -

    A categorize function to be used with add_store, each player has their own value

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that will be converted to a string - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the player's name who owns this element -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - categorize_by_force(element) -
    -
    -
    -
    - -

    A categorize function to be used with add_store, each force has its own value

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that will be converted to a string - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the player's force name who owns this element -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - categorize_by_surface(element) -
    -
    -
    -
    - -

    A categorize function to be used with add_store, each surface has its own value

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that will be converted to a string - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the player's surface name who owns this element -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - draw(name, element) -
    -
    -
    -
    - -

    Draws a copy of the element define to the parent element, see draw_to

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string or table) - - the uid, debug name or define for the element define to draw - -
    • - - - - - -
    • - - element - - : - - (LuaGuiEelement) - - the parent element that it the define will be drawn to - -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - toggle_enabled(element) -
    -
    -
    -
    - -

    Will toggle the enabled state of an element

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the gui element to toggle - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - the new state that the element has -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - toggle_visible(element) -
    -
    -
    -
    - -

    Will toggle the visiblity of an element

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the gui element to toggle - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - the new state that the element has -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - set_padding(element[, up=0][, down=0][, left=0][, right=0]) -
    -
    -
    -
    - -

    Sets the padding for a gui element

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to set the padding for - -
    • - - - - - -
    • - - up - - : - - (number) - - the amount of padding on the top - - (default: 0) -
    • - - - - - -
    • - - down - - : - - (number) - - the amount of padding on the bottom - - (default: 0) -
    • - - - - - -
    • - - left - - : - - (number) - - the amount of padding on the left - - (default: 0) -
    • - - - - - -
    • - - right - - : - - (number) - - the amount of padding on the right - - (default: 0) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - set_padding_style(style[, up=0][, down=0][, left=0][, right=0]) -
    -
    -
    -
    - -

    Sets the padding for a gui style

    -

    - - - Parameters: - -
      - - - - - -
    • - - style - - : - - (LuaStyle) - - the element to set the padding for - -
    • - - - - - -
    • - - up - - : - - (number) - - the amount of padding on the top - - (default: 0) -
    • - - - - - -
    • - - down - - : - - (number) - - the amount of padding on the bottom - - (default: 0) -
    • - - - - - -
    • - - left - - : - - (number) - - the amount of padding on the left - - (default: 0) -
    • - - - - - -
    • - - right - - : - - (number) - - the amount of padding on the right - - (default: 0) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - create_alignment(element[, name][, horizontal_align='right'][, vertical_align='center']) -
    -
    -
    -
    - -

    Allows the creation of an alignment flow to place elements into

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add this alignment into - -
    • - - - - - -
    • - - name - - : - - (string) - - the name to use for the alignment - - (optional) -
    • - - - - - -
    • - - horizontal_align - - : - - (string) - - the horizontal alignment of the elements in this flow - - (default: 'right') -
    • - - - - - -
    • - - vertical_align - - : - - (string) - - the vertical alignment of the elements in this flow - - (default: 'center') -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - destroy_if_valid(element) -
    -
    -
    -
    - -

    Destroies an element but tests for it being present and valid first

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to be destroied - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if it was destoried -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - create_scroll_table(element, table_size, maximal_height[, name='scroll']) -
    -
    -
    -
    - -

    Creates a scroll area with a table inside, table can be any size

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add this scroll into - -
    • - - - - - -
    • - - table_size - - : - - (number) - - the number of columns in the table - -
    • - - - - - -
    • - - maximal_height - - : - - (number) - - the max hieght of the scroll - -
    • - - - - - -
    • - - name - - : - - (string) - - the name of the scoll element - - (default: 'scroll') -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - create_header(element, caption[, tooltip][, right_align][, name='header']) -
    -
    -
    -
    - -

    Creates a header section with a label and button area

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add this header into - -
    • - - - - - -
    • - - caption - - : - - (localeString) - - the caption that is used as the title - -
    • - - - - - -
    • - - tooltip - - : - - (localeString) - - the tooltip that is shown on the caption - - (optional) -
    • - - - - - -
    • - - right_align - - : - - (boolean) - - when true will include the right align area - - (optional) -
    • - - - - - -
    • - - name - - : - - (string) - - the name of the header area - - (default: 'header') -
    • - - -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the header that was made, or the align area if that was created -
    • -
    - - - - - - - - - -
    -
    -

    Buttons

    -
    -
    -
    -
    - # - mod-gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Button.new_button([name]) -
    -
    -
    -
    - -

    Creates a new button element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new button element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Button._prototype:set_sprites(sprite[, hovered_sprite][, clicked_sprite]) -
    -
    -
    -
    - -

    Adds sprites to a button making it a sprite button

    -

    - - - Parameters: - -
      - - - - - -
    • - - sprite - - : - - (SpritePath) - - the sprite path for the default sprite for the button - -
    • - - - - - -
    • - - hovered_sprite - - : - - (SpritePath) - - the sprite path for the sprite when the player hovers over the button - - (optional) -
    • - - - - - -
    • - - clicked_sprite - - : - - (SpritePath) - - the sprite path for the sprite when the player clicks the button - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - returns the button define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Button._prototype:set_click_filter(filter[, ...]) -
    -
    -
    -
    - -

    Adds a click / mouse button filter to the button

    -

    - - - Parameters: - -
      - - - - - -
    • - - filter - - : - - (table) - - ?string|table either a of mouse buttons or the first mouse button to filter, with a table true means allowed - -
    • - - - - - -
    • - - ... - - : - - (table) - - when filter is not a you can add the mouse buttons one after each other - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - returns the button define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Button._prototype:set_key_filter(filter[, ...]) -
    -
    -
    -
    - -

    Adds a control key filter to the button

    -

    - - - Parameters: - -
      - - - - - -
    • - - filter - - : - - (table) - - ?string|table either a of control keys or the first control keys to filter, with a table true means allowed - -
    • - - - - - -
    • - - ... - - : - - (table) - - when filter is not a you can add the control keys one after each other - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - returns the button define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -

    Checkboxs

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.store -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.new_checkbox([name]) -
    -
    -
    -
    - -

    Creates a new checkbox element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new checkbox element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.new_radiobutton([name]) -
    -
    -
    -
    - -

    Creates a new radiobutton element define, has all functions checkbox has

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new button element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox._prototype_radiobutton:add_as_option(option_set, option_name) -
    -
    -
    -
    - -

    Adds this radiobutton to be an option in the given option set (only one can be true at a time)

    -

    - - - Parameters: - -
      - - - - - -
    • - - option_set - - : - - (string) - - the name of the option set to add this element to - -
    • - - - - - -
    • - - option_name - - : - - (string) - - the name of this option that will be used to identify it - -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox._prototype_radiobutton:get_store(category, internal) -
    -
    -
    -
    - -

    Gets the stored value of the radiobutton or the option set if present

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - [opt] the category to get such as player name or force name - -
    • - - - - - -
    • - - internal - - : - - (boolean) - - used to prevent stackover flow - -
    • - - -
    - - - - - Returns: -
      -
    • - (any) - the value that is stored for this define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox._prototype_radiobutton:set_store(category, value, internal) -
    -
    -
    -
    - -

    Sets the stored value of the radiobutton or the option set if present

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - [opt] the category to get such as player name or force name - -
    • - - - - - -
    • - - value - - : - - (boolean) - - the value to set for this define, must be valid for its type ie for checkbox etc - -
    • - - - - - -
    • - - internal - - : - - (boolean) - - used to prevent stackover flow - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if the value was set -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.new_option_set(callback, categorize) -
    -
    -
    -
    - -

    Registers a new option set that can be linked to radiobuttons (only one can be true at a time)

    -

    - - - Parameters: - -
      - - - - - -
    • - - callback - - : - - (function) - - the update callback when the value of the option set changes - callback param - value string - the new selected option for this option set - callback param - category string - the category that updated if categorize was used - -
    • - - - - - -
    • - - categorize - - : - - (function) - - the function used to convert an element into a string - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the name of this option set to be passed to add_as_option -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.draw_option_set(name, element) -
    -
    -
    -
    - -

    Draws all radiobuttons that are part of an option set at once (Gui.draw will not work)

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the option set to draw the radiobuttons of - -
    • - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the parent element that the radiobuttons will be drawn to - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Checkbox.reset_radiobuttons(element[, exclude][, recursive=false]) -
    -
    -
    -
    - -

    Sets all radiobutton in a element to false (unless excluded) and can act recursively

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the root gui element to start setting radio buttons from - -
    • - - - - - -
    • - - exclude - - : - - (table) - - ?string|table the name of the radiobutton to exclude or a of radiobuttons where true will set the state true - - (optional) -
    • - - - - - -
    • - - recursive - - : - - (number or boolean) - - if true will recur as much as possible, if a will recur that number of times - - (default: false) -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if successful -
    • -
    - - - - - - - - - -
    -
    -

    Dropdowns

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Dropdown.new_dropdown([name]) -
    -
    -
    -
    - -

    Creates a new dropdown element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new dropdown element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown.new_list_box([name]) -
    -
    -
    -
    - -

    Creates a new list box element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new list box element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown._prototype:new_static_options(options[, ...], the) -
    -
    -
    -
    - -

    Adds new static options to the dropdown which will trigger the general callback

    -

    - - - Parameters: - -
      - - - - - -
    • - - options - - : - - (table) - - ?string|table either a of option strings or the first option string, with a table values are the options - -
    • - - - - - -
    • - - ... - - : - - (table) - - when options is not a you can add the options one after each other - - (optional) -
    • - - - - - -
    • - - the - - : - - (self) - - define to allow chaining - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Dropdown._prototype:new_dynamic_options(callback) -
    -
    -
    -
    - -

    Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options)

    -

    - - - Parameters: - -
      - - - - - -
    • - - callback - - : - - (function) - - the function that will run to get the options for the dropdown - callback param - player LuaPlayer - the player that the element is being drawn to - callback param - element LuaGuiElement - the element that is being drawn - callback return - table - the values of this table will be appended to the static options of the dropdown - -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown._prototype:add_option_callback(option, callback) -
    -
    -
    -
    - -

    Adds a case specific callback which will only run when that option is selected (general case still triggered)

    -

    - - - Parameters: - -
      - - - - - -
    • - - option - - : - - (string) - - the name of the option to trigger the callback on; if not already added then will be added as an option - -
    • - - - - - -
    • - - callback - - : - - (function) - - the function that will be called when that option is selected - callback param - player LuaPlayer - the player who owns the gui element - callback param - element LuaGuiElement - the element which is being effected - callback param - value string - the new option that has been selected - -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown.select_value(element, value) -
    -
    -
    -
    - -

    Selects the option from a dropdown or list box given the value rather than key

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that contains the option - -
    • - - - - - -
    • - - value - - : - - (string) - - the option to select from the dropdown - -
    • - - -
    - - - - - Returns: -
      -
    • - (number) - the key where the value was -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Dropdown.get_selected_value(element) -
    -
    -
    -
    - -

    Returns the currently selected value rather than index

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the gui element that you want to get the value of - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the value that is currently selected -
    • -
    - - - - - - - - - -
    -
    -

    Elem Buttons

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - ElemButton.new_elem_button([name]) -
    -
    -
    -
    - -

    Creates a new elem button element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new elem button element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - ElemButton._prototype.set_type -
    -
    -
    -
    - -

    Sets the type of the elem button, the type is required so this must be called at least once

    +

    Called when the player opens a GUI.

    @@ -7231,13 +980,13 @@
  • - type + handler : - (string) + (function) - the type that this elem button is see factorio api + the event handler which will be called
  • @@ -7260,18 +1009,17 @@
    - # - ElemButton._prototype:set_default(value) + # + Gui._prototype_element.on_closed
    -

    Sets the default value for the elem button, this may be a function or a string

    +

    Called when the player closes the GUI they have open.

    - Parameters:
      @@ -7279,15 +1027,15 @@ -
    • +
    • - value + handler : - (string or function) + (function) - string a will be a static default and a function will be called when drawn to get the default + the event handler which will be called
    • @@ -7297,13 +1045,496 @@ - Returns: + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_click +
    +
    +
    +
    + +

    Called when LuaGuiElement is clicked.

    +

    + + +
      -
    • - (the) - element define to allow for chaining + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called +
    • + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_confirmed +
    +
    +
    +
    + +

    Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_checked_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_elem_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement element value is changed (related to choose element buttons).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_location_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement element location is changed (related to frames in player.gui.screen).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_tab_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement selected tab is changed (related to tabbed-panes).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_selection_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_switch_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement switch state is changed (related to switches).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_text_change +
    +
    +
    +
    + +

    Called when LuaGuiElement text is changed by the player.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_value_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement slider value is changed (related to the slider element).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + @@ -7315,121 +1546,48 @@
    -

    Progress Bars

    +

    Top Flow

    - # - expcore.gui.core + # + toggle_top_flow
    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.global -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar.set_maximum(element, amount) -
    -
    -
    -
    - -

    Sets the maximum value that represents the end value of the progress bar

    +

    Button which toggles the top flow elements

    + + + + + + + + + + + + + +
    +
    +
    +
    + # + get_top_flow(player) +
    +
    +
    +
    + +

    Gets the flow which contains the elements for the top flow

    +

    (player)

    + Parameters: @@ -7441,271 +1599,13 @@
  • - element + player : - (LuaGuiElement or string) + (LuaPlayer) - either a gui element or a registered define - -
  • - - - - - -
  • - - amount - - : - - (number) - - the amount to have set as the maximum - -
  • - - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar.increment(element[, amount=1]) -
    -
    -
    -
    - -

    Increases the value of the progressbar, if a define is given all of its instances have incremented

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement or string) - - either a gui element or a registered define - -
    • - - - - - -
    • - - amount - - : - - (number) - - the amount to increase the progressbar by - - (default: 1) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar.decrement(element[, amount=1]) -
    -
    -
    -
    - -

    Decreases the value of the progressbar, if a define is given all of its instances have decremented

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement or string) - - either a gui element or a registered define - -
    • - - - - - -
    • - - amount - - : - - (number) - - the amount to decrease the progressbar by - - (default: 1) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar.new_progressbar([name]) -
    -
    -
    -
    - -

    Creates a new progressbar element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new progressbar element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:set_default_maximum(amount) -
    -
    -
    -
    - -

    Sets the maximum value that represents the end value of the progress bar

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to have set as the maximum + the player that you want to get the flow for
    • @@ -7718,8 +1618,8 @@ Returns: @@ -7729,20 +1629,23 @@ + Usage: +
      -- Geting your top element flow
      +local top_flow = Gui.get_top_flow(game.player)
    - # - ProgressBar._prototype:use_count_down([state=true]) + # + update_top_flow(player)
    -

    Will set the progress bar to start at 1 and trigger when it hits 0

    +

    Updates the visible states of all the elements on a players top flow

    @@ -7754,6 +1657,75 @@ +
  • + + player + + : + + (LuaPlayer) + + the player that you want to update the flow for + +
  • + + + + + + + + + + + + + + + Usage: +
    -- Update your flow
    +Gui.update_top_flow(game.player)
    + + +
    +
    +
    +
    + # + toggle_top_flow(player[, state]) +
    +
    +
    +
    + +

    Toggles the visible states of all the elements on a players top flow

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to toggle the flow for + +
    • + + + + +
    • state @@ -7762,453 +1734,7 @@ (boolean) - when true the bar will start filled, to be used with decrease - - (default: true) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:increment([amount=1][, category]) -
    -
    -
    -
    - -

    Increases the value of the progressbar

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to increase the progressbar by - - (default: 1) -
    • - - - - - -
    • - - category - - : - - (string) - - the category that is used with a store - - (optional) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:increment_filtered([amount=1], filter) -
    -
    -
    -
    - -

    Increases the value of the progressbar, if the filter condition is met, does not work with store

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to increase the progressbar by - - (default: 1) -
    • - - - - - -
    • - - filter - - : - - (function) - - the filter to be used - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:decrement([amount=1][, category]) -
    -
    -
    -
    - -

    Decreases the value of the progressbar

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to decrease the progressbar by - - (default: 1) -
    • - - - - - -
    • - - category - - : - - (string) - - the category that is used with a store - - (optional) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:decrement_filtered([amount=1], filter) -
    -
    -
    -
    - -

    Decreases the value of the progressbar, if the filter condition is met, does not work with store

    -

    - - - Parameters: - -
      - - - - - -
    • - - amount - - : - - (number) - - the amount to decrease the progressbar by - - (default: 1) -
    • - - - - - -
    • - - filter - - : - - (function) - - the filter to be used - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:add_element(element[, maximum]) -
    -
    -
    -
    - -

    Adds an element into the list of instances that will are waiting to complete, does not work with store - note use store if you want persistent data, this only stores the elements not the values which they have

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that you want to add into the waiting to complete list - -
    • - - - - - -
    • - - maximum - - : - - (number) - - the maximum for this element if not given the default for this define is used - - (optional) -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:reset_element(element) -
    -
    -
    -
    - -

    Resets an element, or its store, to be back at the start, either 1 or 0

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that you want to reset the progress of - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:event_counter([filter]) -
    -
    -
    -
    - -

    Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented

    -

    - - - Parameters: - -
      - - - - - -
    • - - filter - - : - - (function) - - when given will use filtered increment + if given then the state will be set to this state (optional)
    • @@ -8222,66 +1748,8 @@ Returns: - - - - - - - - - -
    -
    -
    -
    - # - ProgressBar._prototype:event_countdown([filter]) -
    -
    -
    -
    - -

    Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented

    -

    - - - Parameters: - -
      - - - - - -
    • - - filter - - : - - (function) - - when given will use filtered decrement - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (function) - the event handler + (boolean) + the new visible state of the top flow
    @@ -8291,22 +1759,29 @@ + Usage: +
    -- Toggle your flow
    +Gui.toggle_top_flow(game.player)
    +
    -- Open your top flow
    +Gui.toggle_top_flow(game.player,true)
    -

    Sliders

    +

    Left Flow

    - # - expcore.gui.core + # + hide_left_flow
    +

    Button which hides the elements in the left flow

    +

    @@ -8325,18 +1800,50 @@
    - # - expcore.gui.prototype + # + get_left_flow(player)
    +

    Gets the flow which contains the elements for the left flow

    +

    (player)

    + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to get the flow for + +
    • + + +
    + + Returns: + @@ -8344,70 +1851,23 @@ + Usage: +
    -- Geting your left element flow
    +local left_flow = Gui.get_left_flow(game.player)
    - # - expcore.gui.instances + # + hide_left_flow(player)
    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Slider.new_slider([name]) -
    -
    -
    -
    - -

    Creates a new slider element define

    +

    Hides all left elements for a player

    @@ -8421,15 +1881,14 @@
  • - name + player : - (string) + (LuaPlayer) - the optional debug name that can be added + the player to hide the elements for - (optional)
  • @@ -8438,174 +1897,70 @@ - Returns: + + + + + + + + Usage: +
    -- Hide your left elements
    +Gui.hide_left_flow(game.player)
    + + +
    +
    +
    +
    + # + toggle_left_element(player, element_define[, state]) +
    +
    +
    +
    + +

    Toggles the visible state of all a left element for a player

    +

    + + + Parameters: +
      -
    • + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to toggle the element for + +
    • + + + + + +
    • + + element_define + + : + (table) - the new slider element define -
    • -
    - - - - - - - - -
    -
    -
    -
    - # - Slider._prototype:set_range([min][, max]) -
    -
    -
    -
    - -

    Sets the range of a slider, if not used will use default values for a slider

    -

    - - - Parameters: - -
      - - - - - -
    • - - min - - : - - (number) - - the minimum value that the slider can take - - (optional) -
    • - - - - - -
    • - - max - - : - - (number) - - the maximum value that the slider can take - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Slider._prototype:draw_label(element) -
    -
    -
    -
    - -

    Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the parent element that the label will be drawn to + the element that you want to toggle for the player
    • -
    - - - - - Returns: -
      -
    • - (LuaGuiElement) - the new label element so that styles can be applied -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Slider._prototype:enable_auto_draw_label([state=true]) -
    -
    -
    -
    - -

    Enables auto draw of the label, the label will share the same parent element as the slider

    -

    - - - Parameters: - -
      - - @@ -8617,2174 +1972,7 @@ (boolean) - when false will disable the auto draw of the label - - (default: true) - - - -
    - - - - - Returns: -
      -
    • - (self) - the define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -

    Text

    -
    -
    -
    -
    - # - expcore.gui.core -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.prototype -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Text.new_text_field([name]) -
    -
    -
    -
    - -

    Creates a new text field element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new text field element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Text.new_text_box([name]) -
    -
    -
    -
    - -

    Creates a new text box element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the optional debug name that can be added - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new text box element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Text._prototype_box:set_selectable([state=true]) -
    -
    -
    -
    - -

    Sets the text box to be selectable

    -

    - - - Parameters: - -
      - - - - - -
    • - - state - - : - - (boolean) - - when false will set the state to false - - (default: true) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - table the define to allow for chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Text._prototype_box:set_word_wrap([state=true]) -
    -
    -
    -
    - -

    Sets the text box to have word wrap

    -

    - - - Parameters: - -
      - - - - - -
    • - - state - - : - - (boolean) - - when false will set the state to false - - (default: true) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - table the define to allow for chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Text._prototype_box:set_read_only([state=true]) -
    -
    -
    -
    - -

    Sets the text box to be read only

    -

    - - - Parameters: - -
      - - - - - -
    • - - state - - : - - (boolean) - - when false will set the state to false - - (default: true) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - table the define to allow for chaining -
    • -
    - - - - - - - - - -
    -
    -

    Instances

    -
    -
    -
    -
    - # - utils.global -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Instances.has_categories(name) -
    -
    -
    -
    - -

    Returns if a instance group has a serializer function; must be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if there is a serializer function -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.is_registered(name) -
    -
    -
    -
    - -

    Returns if the given name is a registered instance group

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group you are testing - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if the name is registered -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.register(name[, serializer]) -
    -
    -
    -
    - -

    Registers the name of an instance group to allow for storing element instances

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group; must to unique - -
    • - - - - - -
    • - - serializer - - : - - (function) - - function used to turn the element into a string - serializer param - element LuaGuiElement - the gui element to be turned into a string - serializer return - string - the category that the element will be added to like the player's name or force's name - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the name that was added so it can be used as a variable -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.add_element(name, element) -
    -
    -
    -
    - -

    Adds an element to the instance group under the correct category; must be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to add the element to - -
    • - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add the the instance group - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Instances.get_elements_raw(name[, category]) -
    -
    -
    -
    - -

    Gets all element instances without first removing any invalid ones; used internally and must be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to get the instances of - -
    • - - - - - -
    • - - category - - : - - (string) - - the category to get the instance from, not needed when no serializer function - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the table of element instances of which some may be invalid -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.get_valid_elements(name[, category][, callback]) -
    -
    -
    -
    - -

    Gets all valid element instances and has the option of running a callback on those that are valid

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to get the instances of - -
    • - - - - - -
    • - - category - - : - - (string) - - the category to get the instances of, not needed when no serializer function - - (optional) -
    • - - - - - -
    • - - callback - - : - - (function) - - when given the callback will be ran on all valid elements - callback param - element LuaGuiElement - the current valid element - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the table of element instances with all invalid ones removed -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Instances.unregistered_add_element(name, category, element) -
    -
    -
    -
    - -

    A version of add_element that does not require the group to be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to add the element to - -
    • - - - - - -
    • - - category - - : - - (string or nil) - - the category to add the element to, can be nil but must still be given - -
    • - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element to add to the instance group - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Instances.unregistered_get_elements(name, category[, callback]) -
    -
    -
    -
    - -

    A version of get_elements that does not require the group to be registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - name - - : - - (string) - - the name of the instance group to get the instances of - -
    • - - - - - -
    • - - category - - : - - (string or nil) - - the category to get the instances of, can be nil but must still be given - -
    • - - - - - -
    • - - callback - - : - - (function) - - when given will be called on all valid instances - callback param - element LuaGuiElement - the current valid element - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the table of element instances with all invalid ones removed -
    • -
    - - - - - - - - - -
    -
    -

    Prototype

    -
    -
    -
    -
    - # - utils.game -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.store -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.gui.instances -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - Constructor.event(event_name) -
    -
    -
    -
    - -

    Creates a new function to add functions to an event handler

    -

    - - - Parameters: - -
      - - - - - -
    • - - event_name - - : - - (string) - - the name of the event that callbacks will be added to - -
    • - - -
    - - - - - Returns: -
      -
    • - (function) - the function used to register handlers -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Constructor.extend(new_prototype) -
    -
    -
    -
    - -

    Extents a prototype with the base functions of all gui prototypes, no metatables

    -

    - - - Parameters: - -
      - - - - - -
    • - - new_prototype - - : - - (table) - - the prototype that you want to add the functions to - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the same prototype but with the new functions added -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Constructor.store(callback) -
    -
    -
    -
    - -

    Creates a new function which adds a store to a gui define

    -

    - - - Parameters: - -
      - - - - - -
    • - - callback - - : - - (function) - - the function called when needing to update the value of an element - -
    • - - -
    - - - - - Returns: -
      -
    • - (function) - the function that will add a store for this define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Constructor.setter(value_type, key[, second_key]) -
    -
    -
    -
    - -

    Creates a setter function that checks the type when a value is set

    -

    - - - Parameters: - -
      - - - - - -
    • - - value_type - - : - - (string) - - the type that the value should be when it is set - -
    • - - - - - -
    • - - key - - : - - (string) - - the key of the define that will be set - -
    • - - - - - -
    • - - second_key - - : - - (string) - - allows for setting of a key in a sub table - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (function) - the function that will check the type and set the value -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:uid() -
    -
    -
    -
    - -

    Gets the uid for the element define

    -

    - - - - - - Returns: -
      -
    • - (string) - the uid of this element define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype.debug_name -
    -
    -
    -
    - -

    Sets a debug alias for the define

    -

    - - - -
      - - - - - -
    • - - name - - : - - (string) - - the debug name for the element define that can be used to get this element define - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.set_caption -
    -
    -
    -
    - -

    Sets the caption for the element define

    -

    - - - -
      - - - - - -
    • - - caption - - : - - (string) - - the caption that will be drawn with the element - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.set_tooltip -
    -
    -
    -
    - -

    Sets the tooltip for the element define

    -

    - - - -
      - - - - - -
    • - - tooltip - - : - - (string) - - the tooltip that will be displayed for this element when drawn - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.set_pre_authenticator -
    -
    -
    -
    - -

    Sets an authenticator that blocks the draw function if check fails

    -

    - - - -
      - - - - - -
    • - - callback - - : - - (function) - - the function that will be ran to test if the element should be drawn or not - callback param - LuaPlayer player - the player that the element is being drawn to - callback param - string define_name - the name of the define that is being drawn - callback return - boolean - false will stop the element from being drawn - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.set_post_authenticator -
    -
    -
    -
    - -

    Sets an authenticator that disables the element if check fails

    -

    - - - -
      - - - - - -
    • - - callback - - : - - (function) - - the function that will be ran to test if the element should be enabled or not - callback param - LuaPlayer player - the player that the element is being drawn to - callback param - string define_name - the name of the define that is being drawn - callback return - boolean - false will disable the element - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.on_draw -
    -
    -
    -
    - -

    Registers a callback to the on_draw event

    -

    - - - -
      - - - - - -
    • - - callback - - : - - (function) - - - callback param - LuaPlayer player - the player that the element was drawn to - callback param - LuaGuiElement element - the element that was drawn - callback param - any ... - any other params passed by the draw_to function - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype.on_style_update -
    -
    -
    -
    - -

    Registers a callback to the on_style_update event

    -

    - - - -
      - - - - - -
    • - - callback - - : - - (function) - - - callback param - LuaStyle style - the style that was changed and/or needs changing - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Prototype:set_style(style[, callback]) -
    -
    -
    -
    - -

    Sets the style for the element define

    -

    - - - Parameters: - -
      - - - - - -
    • - - style - - : - - (string) - - the style that will be used for this element when drawn - -
    • - - - - - -
    • - - callback - - : - - (function) - - function is called when element is drawn to alter its style - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the element define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:set_embedded_flow(state) -
    -
    -
    -
    - -

    Sets the element to be drawn inside a nameless flow, can be given a name using a function

    -

    - - - Parameters: - -
      - - - - - -
    • - - state - - : - - (boolean or function) - - when true a padless flow is created to contain the element - -
    • - - -
    - - - - - Returns: -
      -
    • - (self) - the element define to allow chaining -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:raise_event(event_name, ...) -
    -
    -
    -
    - -

    Raises a custom event for this define, any number of params can be given

    -

    - - - Parameters: - -
      - - - - - -
    • - - event_name - - : - - (string) - - the name of the event that you want to raise - -
    • - - - - - -
    • - - ... - - : - - (any) - - any params that you want to pass to the event - -
    • - - -
    - - - - - Returns: -
      -
    • - (number) - the number of handlers that were registered -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:draw_to(element) -
    -
    -
    -
    - -

    The main function for defines, when called will draw an instance of this define to the given element - what is drawn is based on the data in draw_data which is set using other functions

    -

    - - - Parameters: - -
      - - - - - -
    • - - element - - : - - (LuaGuiElement) - - the element that the define will draw a instance of its self onto - -
    • - - -
    - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    - # - Prototype:get_store(category) -
    -
    -
    -
    - -

    Gets the value in this elements store, category needed if serializer function used

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - [opt] the category to get such as player name or force name - -
    • - - -
    - - - - - Returns: -
      -
    • - (any) - the value that is stored for this define -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:set_store(category, value) -
    -
    -
    -
    - -

    Sets the value in this elements store, category needed if serializer function used

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - [opt] the category to get such as player name or force name - -
    • - - - - - -
    • - - value - - : - - (any) - - the value to set for this define, must be valid for its type ie for checkbox etc - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if the value was set -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - Prototype:clear_store([category]) -
    -
    -
    -
    - -

    Sets the value in this elements store to nil, category needed if serializer function used

    -

    - - - Parameters: - -
      - - - - - -
    • - - category - - : - - (string) - - the category to get such as player name or force name + if given then the state will be set to this state (optional)
    • @@ -10799,7 +1987,7 @@
      • (boolean) - true if the value was set + the new visible state of the element
      @@ -10809,134 +1997,11 @@ - - -
    -
    -

    Test

    -
    -
    -
    -
    - # - expcore.gui -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.common -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - resources.color_presets -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - utils.event -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.store -
    -
    -
    -
    - - - - - - - - - - - - - + Usage: +
    -- Toggle your example button
    +Gui.toggle_top_flow(game.player,example_flow_with_button)
    +
    -- Open your example button
    +Gui.toggle_top_flow(game.player,example_flow_with_button,true)
    @@ -10955,7 +2020,7 @@ generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index 00b18e72..d684f92e 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -1432,7 +1432,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index 3f2be0c2..2e261b19 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -3152,7 +3152,7 @@ generated by LDoc diff --git a/docs/core/Store.html b/docs/core/Store.html index 1d8ad527..c977f109 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -1464,7 +1464,7 @@ Store.set(player_scores,game.player,10) generated by LDoc diff --git a/docs/core/Sudo.html b/docs/core/Sudo.html index 23573d85..ea78d5a3 100644 --- a/docs/core/Sudo.html +++ b/docs/core/Sudo.html @@ -544,7 +544,7 @@ generated by LDoc diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index da3e4e7f..d1ca6a0e 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -626,7 +626,7 @@ generated by LDoc diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index cd01fbd5..21253ddc 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -629,7 +629,7 @@ generated by LDoc diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 7a48f8dc..3dc31aa5 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -449,7 +449,7 @@ generated by LDoc diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index 44170d3b..454a6901 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -632,7 +632,7 @@ generated by LDoc diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index 196ec539..a4647a51 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -837,7 +837,7 @@ generated by LDoc diff --git a/docs/index.html b/docs/index.html index 4601a828..cd8ed91c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -57,10 +57,7 @@ Gui Core Module - Gui - - This file is used to require all the different elements of the gui module - - each module has an outline here but for more details see their separate files in ./gui - - please read the files for more documentation that cant be shown here - - please note there is a rework planned but not started +- Used to define new gui elements and gui event handlers Permissions-Groups @@ -514,7 +511,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index 75103f1b..2b73d7da 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -351,7 +351,7 @@ generated by LDoc diff --git a/docs/modules/utils.alien_evolution_progress.html b/docs/modules/utils.alien_evolution_progress.html index 51092a84..fc152587 100644 --- a/docs/modules/utils.alien_evolution_progress.html +++ b/docs/modules/utils.alien_evolution_progress.html @@ -419,7 +419,7 @@ fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on generated by LDoc diff --git a/docs/modules/utils.core.html b/docs/modules/utils.core.html index 31b33120..d3a78a5d 100644 --- a/docs/modules/utils.core.html +++ b/docs/modules/utils.core.html @@ -1164,7 +1164,7 @@ generated by LDoc diff --git a/docs/modules/utils.debug.html b/docs/modules/utils.debug.html index 3d92af43..661eb841 100644 --- a/docs/modules/utils.debug.html +++ b/docs/modules/utils.debug.html @@ -654,7 +654,7 @@ generated by LDoc diff --git a/docs/modules/utils.dump_env.html b/docs/modules/utils.dump_env.html index e54ef510..fff59dbb 100644 --- a/docs/modules/utils.dump_env.html +++ b/docs/modules/utils.dump_env.html @@ -323,7 +323,7 @@ generated by LDoc diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index 87ca10a6..663e8dcb 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -1292,7 +1292,7 @@ generated by LDoc diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index e9fcbde4..26e97c55 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -434,7 +434,7 @@ generated by LDoc diff --git a/docs/modules/utils.math.html b/docs/modules/utils.math.html index 12045d90..c192045d 100644 --- a/docs/modules/utils.math.html +++ b/docs/modules/utils.math.html @@ -353,7 +353,7 @@ generated by LDoc diff --git a/docs/modules/utils.recipe_locker.html b/docs/modules/utils.recipe_locker.html index 59d49a86..51c8fb76 100644 --- a/docs/modules/utils.recipe_locker.html +++ b/docs/modules/utils.recipe_locker.html @@ -441,7 +441,7 @@ generated by LDoc diff --git a/docs/modules/utils.state_machine.html b/docs/modules/utils.state_machine.html index 68e88fea..5708101d 100644 --- a/docs/modules/utils.state_machine.html +++ b/docs/modules/utils.state_machine.html @@ -752,7 +752,7 @@ generated by LDoc diff --git a/docs/modules/utils.table.html b/docs/modules/utils.table.html index 5ffe1e8b..2c9404e6 100644 --- a/docs/modules/utils.table.html +++ b/docs/modules/utils.table.html @@ -1418,7 +1418,7 @@ generated by LDoc diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index cfc96b04..f1a4a0be 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -651,7 +651,7 @@ generated by LDoc diff --git a/docs/modules/utils.timestamp.html b/docs/modules/utils.timestamp.html index fcf4b838..c22b2df7 100644 --- a/docs/modules/utils.timestamp.html +++ b/docs/modules/utils.timestamp.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index 1eab766f..6901e6e6 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -789,7 +789,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index 46789283..e472eb59 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -228,26 +228,29 @@

    ExpGaming Scenario Repository

    ## Explosive Gaming -

    Explosive Gaming (often ExpGaming) is a server hosting community with a strong focus on Factorio and games that follow similar ideas. Our factorio server are known for hosting large maps with the main goal of being a "mega base" which can produce as much as possible with in our reset schedule. Although these server tend to the more experienced players our server are open to everyone. You can find us through our [website], [discord], [wiki], or in the public games tab in factorio (ExpGaming S1). +

    Explosive Gaming (often ExpGaming) is a server hosting community with a strong focus on Factorio and games that follow similar ideas. Our Factorio server are known for hosting large maps with the main goal of being a "mega base" which can produce as much as possible within our reset schedule. Although these servers tend to attract the more experienced players, our servers are open to everyone. You can find us through our [website], [discord], [wiki], or in the public games tab in Factorio (ExpGaming S1, ExpGaming S2, etc.).

    ## Use and Installation

    1) Download this [git repository](https://github.com/explosivegaming/scenario/archive/master.zip) for the stable release. The dev branch can be found [here](https://github.com/explosivegaming/scenario/archive/dev.zip) for those who want the latest features. See [releases](#releases) for other release branches. -

    2) Extract the downloaded zip file from the branch you downloaded into factorio's scenario directory: +

    2) Extract the downloaded zip file from the branch you downloaded into Factorio's scenario directory: * Windows: `%appdata%\Factorio\scenarios` * Linux: `~/.factorio/scenarios`

    3) Within the scenario you can find `./config/_file_loader.lua` which contains a list of all the modules that will be loaded by the scenario; simply comment out (or remove) features you do not want but note that some modules may load other modules as dependencies even when removed from the list.

    4) More advanced users may want to play with the other configs files within `./config` but please be aware that some of the config files will require a basic understanding of lua while others may just be a list of values. -

    5) Once you have made any config changes that you wish to make open factorio, select play, then start scenario (or host scenario from within multiplayer tab), and select the scenario which will be called `scenario-master` if you have downloaded the latest stable release and have not changed the folder name. -

    6) The scenario will now load all the selected modules and start the map, any errors or exceptions raised in the scenario should not cause a game/server crash so if any features don't work as expected then it may be returning an error in the log, please report these errors to [the issues page](issues). +

    5) Once you have made any config changes that you wish to make open Factorio, select play, then start scenario (or host scenario from within multiplayer tab), and select the scenario which will be called `scenario-master` if you have downloaded the latest stable release and have not changed the folder name. +

    6) The scenario will now load all the selected modules and start the map, any errors or exceptions raised in the scenario should not cause a game/server crash, so if any features do not work as expected then it may be returning an error in the log. +Please report these errors to [the issues page](issues).

    ## Contributing -

    All are welcome to make pull requests and issues for this scenario, if you are in any doubt please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. All our docs can be found [here][docs]. Please keep in mind while making code changes: +

    All are welcome to make pull requests and issues for this scenario, if you are in any doubt, please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. All our docs can be found [here][docs]. Please keep in mind while making code changes:

    * New features should have the branch names: `feature/feature-name` -* New features are merged into `dev` after it has been completed. -* After a number of features have been added a release branch is made: `release/X.Y.0`; this branch should have no new features and only bug fixes or localization. -* A release is merged into `master` on the following friday in time for the the weekly reset. -* Patches may be named `patch/X.Y.Z` and fill be merged into `master` and `dev` when appropriate. +* New features are merged into `dev` after it has been completed, this can be done through a pull request. +* After a number of features have been added a release branch is made: `release/X.Y.0` +* Bug fixes and localization can be made to the release branch with a pull request rather than into dev. +* A release is merged into `master` on the following friday after it is considered stable. +* Patches may be named `patch/X.Y.Z` and will be merged into `dev` and then `master` when appropriate.

    ## Releases

    | Scenario Version* | Version Name | Factorio Version** | |---|---|---| +| [v5.10][s5.10] | Data Store Rewrite | [v0.17.71][f0.17.71] | | [v5.9][s5.9] | Control Modules and Documentation | [v0.17.63][f0.17.63] | | [v5.8][s5.8] | Home and Chat Bot | [v0.17.47][f0.17.49] | | [v5.7][s5.7] | Warp System | [v0.17.47][f0.17.47] | @@ -265,7 +268,8 @@ | [v0.1][s0.1] | First Tracked Version | [v0.14][f0.14] |

    \* Scenario patch versions have been omitted.

    \*\* Factorio versions show the version they were made for, often the minimum requirement. -

    [s5.9]: https://github.com/explosivegaming/scenario/releases/tag/5.9.0 +

    [s5.10]: https://github.com/explosivegaming/scenario/releases/tag/5.10.0 +[s5.9]: https://github.com/explosivegaming/scenario/releases/tag/5.9.0 [s5.8]: https://github.com/explosivegaming/scenario/releases/tag/5.8.0 [s5.7]: https://github.com/explosivegaming/scenario/releases/tag/5.7.0 [s5.6]: https://github.com/explosivegaming/scenario/releases/tag/5.6.0 @@ -280,7 +284,8 @@ [s2.0]: https://github.com/explosivegaming/scenario/releases/tag/v2.0 [s1.0]: https://github.com/explosivegaming/scenario/releases/tag/v1.0 [s0.1]: https://github.com/explosivegaming/scenario/releases/tag/v0.1 -

    [f0.17.63]: https://wiki.factorio.com/Version_history/0.17.0#0.17.63 +

    [f0.17.71]: https://wiki.factorio.com/Version_history/0.17.0#0.17.71 +[f0.17.63]: https://wiki.factorio.com/Version_history/0.17.0#0.17.63 [f0.17.49]: https://wiki.factorio.com/Version_history/0.17.0#0.17.49 [f0.17.47]: https://wiki.factorio.com/Version_history/0.17.0#0.17.47 [f0.17.44]: https://wiki.factorio.com/Version_history/0.17.0#0.17.44 @@ -333,7 +338,7 @@ generated by LDoc

    diff --git a/expcore/gui.lua b/expcore/gui.lua index 82257d43..8e25a7c3 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -1,284 +1,489 @@ --[[-- Core Module - Gui - - This file is used to require all the different elements of the gui module - - each module has an outline here but for more details see their separate files in ./gui - - please read the files for more documentation that cant be shown here - - please note there is a rework planned but not started - @core Gui - @alias Gui +- Used to define new gui elements and gui event handlers +@core Gui +@alias Gui + +@usage-- Defining a button that prints the player's name +local example_button = +Gui.new_element{ + type = 'button', + caption = 'Example Button' +} +:on_click(function(event) + local player = event.player + player.print(player.name) +end) + +@usage-- Defining using a custom function +local example_flow_with_button = +Gui.new_element(function(event_trigger,parent) + local flow = + parent.add{ + name = 'example_flow', + type = 'flow' + } + + local element = + flow.add{ + name = event_trigger, + type = 'button', + caption = 'Example Button' + } + + return element +end) +:on_click(function(event) + local player = event.player + player.print(player.name) +end) + +@usage-- Drawing an element +local exmple_button_element = example_button(parent) +local example_flow_with_button = example_flow_with_button(parent) + ]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core +local Event = require 'utils.event' --- @dep utils.event +local mod_gui = require 'mod-gui' --- @dep mod-gui ---[[ - Core +local Gui = { + --- The current highest uid that is being used, will not increase during runtime + -- @field uid + uid = 0, + --- Contains the uids of the elements that will show on the top flow and the auth function + -- @table top_elements + top_elements = {}, + --- Contains the uids of the elements that will show on the left flow and the open on join function + -- @table left_elements + left_elements = {}, + --- Table of all the elements which have been registed with the draw function and event handlers + -- @table defines + defines = {}, + --- An index used for debuging to find the file where different elements where registered + -- @table file_paths + file_paths = {}, + --- The element prototype which is returned from Gui.new_element + -- @table _prototype_element + _prototype_element = {}, + --- The prototype metatable applied to new element defines + -- @table _mt_element + _mt_element = { + __call = function(self,parent,...) + return self._draw(self.name,parent,...) + end + } +} - Gui.new_define(prototype) --- Used internally to create new element defines from a class prototype - Gui.draw(name,element) --- Draws a copy of the element define to the parent element, see draw_to +Gui._mt_element.__index = Gui._prototype_element - Gui.categorize_by_player(element) --- A categorize function to be used with add_store, each player has their own value - Gui.categorize_by_force(element) --- A categorize function to be used with add_store, each force has its own value - Gui.categorize_by_surface(element) --- A categorize function to be used with add_store, each surface has its own value +--- Element Define. +-- @section elementDefine - Gui.toggle_enabled(element) --- Will toggle the enabled state of an element - Gui.toggle_visible(element) --- Will toggle the visibility of an element - Gui.set_padding(element,up,down,left,right) --- Sets the padding for a gui element - Gui.set_padding_style(style,up,down,left,right) --- Sets the padding for a gui style - Gui.create_alignment(element,flow_name) --- Allows the creation of a right align flow to place elements into - Gui.destroy_if_valid(element) --- Destroys an element but tests for it being present and valid first - Gui.create_scroll_table(element,table_size,maximal_height,name) --- Creates a scroll area with a table inside, table can be any size - Gui.create_header(element,caption,tooltip,right_align,name) --- Creates a header section with a label and button area +--[[-- Base function used to define new elements, can be used with a table or with a function +@tparam ?table|function element_define used to define how the element is draw, using a table is the simplist way of doing this +@treturn table the new element define that is used to register events to this element - Prototype Constructor +@usage-- Defining an element with a table +local example_button = +Gui.new_element{ + type = 'button', + caption = 'Example Button' +} - Constructor.event(event_name) --- Creates a new function to add functions to an event handler - Constructor.extend(new_prototype) --- Extents a prototype with the base functions of all gui prototypes, no metatables - Constructor.store(sync,callback) --- Creates a new function which adds a store to a gui define - Constructor.setter(value_type,key,second_key) --- Creates a setter function that checks the type when a value is set +@usage-- Defining an element with a function +local example_flow_with_button = +Gui.new_element(function(event_trigger,parent) + local flow = + parent.add{ + name = 'example_flow', + type = 'flow' + } - Base Prototype + local element = + flow.add{ + name = event_trigger, + type = 'button', + caption = 'Example Button' + } - Prototype:uid() --- Gets the uid for the element define - Prototype:debug_name(value) --- Sets a debug alias for the define - Prototype:set_caption(value) --- Sets the caption for the element define - Prototype:set_tooltip(value) --- Sets the tooltip for the element define - Prototype:set_style(style,callback) --- Sets the style for the element define - Prototype:set_embedded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function + return element +end) - Prototype:set_pre_authenticator --- Sets an authenticator that blocks the draw function if check fails - Prototype:set_post_authenticator --- Sets an authenticator that disables the element if check fails - - Prototype:raise_event(event_name,...) --- Raises a custom event for this define, any number of params can be given - Prototype:draw_to(element,...) --- The main function for defines, when called will draw an instance of this define to the given element - - Prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used - Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used - Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if categorize function used ]] +function Gui.new_element(element_define) + -- Set the metatable to allow access to register events + local element = setmetatable({}, Gui._mt_element) -local Instances = require 'expcore.gui.instances' --- @dep expcore.gui.instances -Gui.new_instance_group = Instances.registers -Gui.get_instances = Instances.get_elements -Gui.add_instance = Instances.get_elements -Gui.update_instances = Instances.apply_to_elements -Gui.classes.instances = Instances ---[[ - Instances.has_categories(name) --- Returns if a instance group has a categorise function; must be registered - Instances.is_registered(name) --- Returns if the given name is a registered instance group - Instances.register(name,categorise) --- Registers the name of an instance group to allow for storing element instances + -- Increment the uid counter + local uid = Gui.uid + 1 + Gui.uid = uid + local name = tostring(uid) + element.name = name - Instances.add_element(name,element) --- Adds an element to the instance group under the correct category; must be registered - Instances.get_elements_raw(name,category) --- Gets all element instances without first removing any invalid ones; used internally and must be registered - Instances.get_valid_elements(name,category,callback) --- Gets all valid element instances and has the option of running a callback on those that are valid + -- Add the defination function + if type(element_define) == 'table' then + element_define.name = name + element._draw = function(_,parent) + return parent.add(element_define) + end + else + element._draw = element_define + end + + -- Add the define to the base module + local file_path = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) + Gui.file_paths[name] = file_path + Gui.defines[name] = element + + -- Return the element so event handers can be accessed + return element +end + +--[[-- Adds an element to be drawn to the top flow when a player joins +@tparam[opt] function authenticator called during toggle or update to decide if the element should be visible + +@usage-- Adding the example button +example_button:add_to_top_flow(function(player) + -- example button will only show when game time is less than 1 minute + return player.online_time < 3600 +end) - Instances.unregistered_add_element(name,category,element) --- A version of add_element that does not require the group to be registered - Instances.unregistered_get_elements(name,category,callback) --- A version of get_elements that does not require the group to be registered ]] +function Gui._prototype_element:add_to_top_flow(authenticator) + Gui.top_elements[self.name] = authenticator or true +end -local Button = require 'expcore.gui.elements.buttons' --- @dep expcore.gui.elements.buttons -Gui.new_button = Button.new_button -Gui.classes.button = Button ---[[ - Button.new_button(name) --- Creates a new button element define +--[[-- Adds an element to be drawn to the left flow when a player joins +@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible - Button._prototype:on_click(player,element) --- Registers a handler for when the button is clicked - Button._prototype:on_left_click(player,element) --- Registers a handler for when the button is clicked with the left mouse button - Button._prototype:on_right_click(player,element) --- Registers a handler for when the button is clicked with the right mouse button +@usage-- Adding the example button +example_flow_with_button:add_to_left_flow(true) - Button._prototype:set_sprites(sprite,hovered_sprite,clicked_sprite) --- Adds sprites to a button making it a sprite button - Button._prototype:set_click_filter(filter,...) --- Adds a click / mouse button filter to the button - Button._prototype:set_key_filter(filter,...) --- Adds a control key filter to the button ]] +function Gui._prototype_element:add_to_left_flow(open_on_join) + Gui.left_elements[self.name] = open_on_join or false +end -local Checkbox = require 'expcore.gui.elements.checkbox' --- @dep expcore.gui.elements.checkbox -Gui.new_checkbox = Checkbox.new_checkbox -Gui.new_radiobutton = Checkbox.new_radiobutton -Gui.new_radiobutton_option_set = Checkbox.new_option_set -Gui.draw_option_set = Checkbox.draw_option_set -Gui.classes.checkbox = Checkbox ---[[ - Checkbox.new_checkbox(name) --- Creates a new checkbox element define - Checkbox._prototype_checkbox:on_element_update(callback) --- Registers a handler for when an element instance updates - Checkbox._prototype_checkbox:on_store_update(callback) --- Registers a handler for when the stored value updates +-- This function is called for event event +local function general_event_handler(event) + -- Check the element is valid + local element = event.element + if not element or not element.valid then + return + end - Checkbox.new_radiobutton(name) --- Creates a new radiobutton element define - Checkbox._prototype_radiobutton:on_element_update(callback) --- Registers a handler for when an element instance updates - Checkbox._prototype_radiobutton:on_store_update(callback) --- Registers a handler for when the stored value updates - Checkbox._prototype_radiobutton:add_as_option(option_set,option_name) --- Adds this radiobutton to be an option in the given option set (only one can be true at a time) + -- Get the event handler for this element + local handlers = Gui.defines[element.name] + local handler = handlers and handlers[event.name] + if not handler then + return + end - Checkbox.new_option_set(callback,categorize) --- Registers a new option set that can be linked to radiobuttons (only one can be true at a time) - Checkbox.draw_option_set(name,element) --- Draws all radiobuttons that are part of an option set at once (Gui.draw will not work) + -- Get the player for this event + local player = game.players[event.player_index] + if not player or not player.valid then + return + end + event.player = player + + local success, err = pcall(handler,event) + if not success then + error('There as been an error with an event handler for a gui element:\n\t'..err) + end +end + +-- This function returns the event handler adder and registeres the general handler +local function event_handler_factory(event_name) + Event.add(event_name, general_event_handler) + + return function(self,handler) + self[event_name] = handler + return self + end +end + +--- Element Events. +-- @section elementEvents + +--- Called when the player opens a GUI. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_opened = event_handler_factory(defines.events.on_gui_opened) + +--- Called when the player closes the GUI they have open. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_closed = event_handler_factory(defines.events.on_gui_closed) + +--- Called when LuaGuiElement is clicked. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click) + +--- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed) + +--- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed) + +--- Called when LuaGuiElement element value is changed (related to choose element buttons). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed) + +--- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed) + +--- Called when LuaGuiElement selected tab is changed (related to tabbed-panes). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed) + +--- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed) + +--- Called when LuaGuiElement switch state is changed (related to switches). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed) + +--- Called when LuaGuiElement text is changed by the player. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_text_change = event_handler_factory(defines.events.on_gui_text_changed) + +--- Called when LuaGuiElement slider value is changed (related to the slider element). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) + +--- Top Flow. +-- @section topFlow + +--- Button which toggles the top flow elements +-- @element toggle_top_flow +local toggle_top_flow = +Gui.new_element(function(event_trigger,parent) + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'button', + style = mod_gui.button_style, + caption = '<', + tooltip = {'gui_util.button_tooltip'} + } + + -- Change its style + local style = element.style + style.width = 18 + style.height = 36 + style.padding = 0 + style.font = 'default-small-bold' + + -- Return the element + return element +end) +:on_click(function(event) + Gui.toggle_top_flow(event.player) +end) + +--[[-- Gets the flow which contains the elements for the top flow +@function Gui.get_top_flow(player) +@tparam LuaPlayer player the player that you want to get the flow for +@treturn LuaGuiElement the top element flow + +@usage-- Geting your top element flow +local top_flow = Gui.get_top_flow(game.player) - Checkbox.reset_radiobutton(element,exclude,recursive) --- Sets all radiobuttons in a element to false (unless excluded) and can act recursively ]] +Gui.get_top_flow = mod_gui.get_button_flow -local Dropdown = require 'expcore.gui.elements.dropdown' --- @dep expcore.gui.elements.dropdown -Gui.new_dropdown = Dropdown.new_dropdown -Gui.new_list_box = Dropdown.new_list_box -Gui.classes.dropdown = Dropdown ---[[ - Dropdown.new_dropdown(name) --- Creates a new dropdown element define - Dropdown.new_list_box(name) --- Creates a new list box element define +--[[-- Updates the visible states of all the elements on a players top flow +@tparam LuaPlayer player the player that you want to update the flow for - Dropdown._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - Dropdown._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates +@usage-- Update your flow +Gui.update_top_flow(game.player) - Dropdown._prototype:new_static_options(options,...) --- Adds new static options to the dropdown which will trigger the general callback - Dropdown._prototype:new_dynamic_options(callback) --- Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options) - Dropdown._prototype:add_option_callback(option,callback) --- Adds a case specific callback which will only run when that option is selected (general case still triggered) - - Dropdown.select_value(element,value) --- Selects the option from a dropdown or list box given the value rather than key - Dropdown.get_selected_value(element) --- Returns the currently selected value rather than index ]] +function Gui.update_top_flow(player) + local top_flow = Gui.get_top_flow(player) + local toggle_button = top_flow[toggle_top_flow.name] + local is_visible = toggle_button.caption == '<' -local Slider = require 'expcore.gui.elements.slider' --- @dep expcore.gui.elements.slider -Gui.new_slider = Slider.new_slider -Gui.classes.slider = Slider ---[[ - Slider.new_slider(name) --- Creates a new slider element define + -- Set the visible state of all elements in the flow + for name,authenticator in pairs(Gui.top_elements) do + -- Ensure the element exists + local element = top_flow[name] + if not element then + element = Gui.defines[name](top_flow) + end - Slider._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - Slider._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates + -- Set the visible state + element.visible = is_visible and authenticator(player) or false + end +end + +--[[-- Toggles the visible states of all the elements on a players top flow +@tparam LuaPlayer player the player that you want to toggle the flow for +@tparam[opt] boolean state if given then the state will be set to this state +@treturn boolean the new visible state of the top flow + +@usage-- Toggle your flow +Gui.toggle_top_flow(game.player) + +@usage-- Open your top flow +Gui.toggle_top_flow(game.player,true) - Slider._prototype:set_range(min,max) --- Sets the range of a slider, if not used will use default values for a slider - Slider._prototype:draw_label(element) --- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player - Slider._prototype:enable_auto_draw_label(state) --- Enables auto draw of the label, the label will share the same parent element as the slider ]] +function Gui.toggle_top_flow(player,state) + local top_flow = Gui.get_top_flow(player) + local toggle_button = top_flow[toggle_top_flow.name] + local new_state = state or toggle_button.caption == '>' -local Text = require 'expcore.gui.elements.text' --- @dep expcore.gui.elements.text -Gui.new_text_filed = Text.new_text_field -Gui.new_text_box = Text.new_text_box -Gui.classes.text = Text ---[[ - Text.new_text_field(name) --- Creates a new text field element define - Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates - Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates + -- Set the visible state of all elements in the flow + for name,authenticator in pairs(Gui.top_elements) do + top_flow[name].visible = new_state and authenticator(player) or false + end + + -- Change the style of the toggle button + if new_state then + toggle_button.caption = '<' + toggle_button.style.height = 34 + else + toggle_button.caption = '>' + toggle_button.style.height = 24 + end + + return new_state +end + +--- Left Flow. +-- @section leftFlow + +--- Button which hides the elements in the left flow +-- @element hide_left_flow +local hide_left_flow = +Gui.new_element(function(event_trigger,parent) + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'button', + style = mod_gui.button_style, + caption = '<', + tooltip = {'expcore-gui.left-button-tooltip'} + } + + -- Change its style + local style = element.style + style.width = 18 + style.height = 36 + style.padding = 0 + style.font = 'default-small-bold' + + -- Return the element + return element +end) +:on_click(function(event) + Gui.hide_left_flow(event.player) +end) + +--[[-- Gets the flow which contains the elements for the left flow +@function Gui.get_left_flow(player) +@tparam LuaPlayer player the player that you want to get the flow for +@treturn LuaGuiElement the left element flow + +@usage-- Geting your left element flow +local left_flow = Gui.get_left_flow(game.player) - Text.new_text_box(name) --- Creates a new text box element define - Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates - Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates - Text._prototype_box:set_selectable(state) --- Sets the text box to be selectable - Text._prototype_box:set_word_wrap(state) --- Sets the text box to have word wrap - Text._prototype_box:set_read_only(state) --- Sets the text box to be read only ]] +Gui.get_left_flow = mod_gui.get_frame_flow -local ElemButton = require 'expcore.gui.elements.elem-button' --- @dep expcore.gui.elements.elem-button -Gui.new_elem_button = ElemButton.new_elem_button -Gui.classes.elem_button = ElemButton ---[[ - ElemButton.new_elem_button(name) --- Creates a new elem button element define +--[[-- Hides all left elements for a player +@tparam LuaPlayer player the player to hide the elements for - ElemButton._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - ElemButton._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates +@usage-- Hide your left elements +Gui.hide_left_flow(game.player) - ElemButton._prototype:set_type(type) --- Sets the type of the elem button, the type is required so this must be called at least once - ElemButton._prototype:set_default(value) --- Sets the default value for the elem button, this may be a function or a string ]] +function Gui.hide_left_flow(player) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow[hide_left_flow.name] -local ProgressBar = require 'expcore.gui.elements.progress-bar' --- @dep expcore.gui.elements.progress-bar -Gui.new_progressbar = ProgressBar.new_progressbar -Gui.set_progressbar_maximum = ProgressBar.set_maximum -Gui.increment_progressbar = ProgressBar.increment -Gui.decrement_progressbar = ProgressBar.decrement -Gui.classes.progressbar = ProgressBar ---[[ - ProgressBar.set_maximum(element,amount,count_down) --- Sets the maximum value that represents the end value of the progress bar - ProgressBar.increment(element,amount) --- Increases the value of the progressbar, if a define is given all of its instances are incremented - ProgressBar.decrement(element,amount) --- Decreases the value of the progressbar, if a define is given all of its instances are decreased + -- Set the visible state of all elements in the flow + hide_button.visible = false + for name,_ in pairs(Gui.left_elements) do + left_flow[name].visible = false + end +end - ProgressBar.new_progressbar(name) --- Creates a new progressbar element define - ProgressBar._prototype:set_maximum(amount,count_down) --- Sets the maximum value that represents the end value of the progress bar - ProgressBar._prototype:use_count_down(state) --- Will set the progress bar to start at 1 and trigger when it hits 0 - ProgressBar._prototype:increment(amount,category) --- Increases the value of the progressbar - ProgressBar._prototype:increment_filtered(amount,filter) --- Increases the value of the progressbar, if the filter condition is met, does not work with store - ProgressBar._prototype:decrement(amount,category) --- Decreases the value of the progressbar - ProgressBar._prototype:decrement_filtered(amount,filter) --- Decreases the value of the progressbar, if the filter condition is met, does not work with store - ProgressBar._prototype:add_element(element,maximum) --- Adds an element into the list of instances that will are waiting to complete, does not work with store - ProgressBar._prototype:reset_element(element) --- Resets an element, or its store, to be back at the start, either 1 or 0 +--[[-- Toggles the visible state of all a left element for a player +@tparam LuaPlayer player the player that you want to toggle the element for +@tparam table element_define the element that you want to toggle for the player +@tparam[opt] boolean state if given then the state will be set to this state +@treturn boolean the new visible state of the element + +@usage-- Toggle your example button +Gui.toggle_top_flow(game.player,example_flow_with_button) + +@usage-- Open your example button +Gui.toggle_top_flow(game.player,example_flow_with_button,true) - ProgressBar._prototype:on_complete(callback) --- Triggers when a progress bar element completes (hits 0 or 1) - ProgressBar._prototype:on_complete(callback) --- Triggers when a store value completes (hits 0 or 1) - ProgressBar._prototype:event_counter(filter) --- Event handler factory that counts up by 1 every time the event triggers, can filter which elements are incremented - ProgressBar._prototype:event_countdown(filter) --- Event handler factory that counts down by 1 every time the event triggers, can filter which elements are decremented ]] +function Gui.toggle_left_element(player,element_define,state) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow[hide_left_flow.name] -local Toolbar = require 'expcore.gui.concepts.toolbar' --- @dep expcore.gui.concepts.toolbar -Gui.new_toolbar_button = Toolbar.new_button -Gui.add_button_to_toolbar = Toolbar.add_button -Gui.update_toolbar = Toolbar.update -Gui.classes.toolbar = Toolbar ---[[ - Toolbar.new_button(name) --- Adds a new button to the toolbar - Toolbar.add_button(button) --- Adds an existing buttton to the toolbar - Toolbar.update(player) --- Updates the player's toolbar with an new buttons or expected change in auth return -]] + -- Set the visible state + local element = left_flow[element_define.name] + local new_state = state or not element.visible + element.visible = new_state -local LeftFrames = require 'expcore.gui.concepts.left' --- @dep expcore.gui.concepts.left -Gui.get_left_frame_flow = LeftFrames.get_flow -Gui.toggle_left_frame = LeftFrames.toggle_frame -Gui.new_left_frame = LeftFrames.new_frame -Gui.classes.left_frames = LeftFrames ---[[ - LeftFrames.get_flow(player) --- Gets the left frame flow for a player - LeftFrames.get_frame(name,player) --- Gets one frame from the left flow by its name - LeftFrames.get_open(player) --- Gets all open frames for a player, if non are open it will remove the close all button - LeftFrames.toggle_frame(name,player,state) --- Toggles the visibility of a left frame, or sets its visibility state + -- Check if the hide button should be visible + local show_hide_button = false + for name,_ in pairs(Gui.left_elements) do + if left_flow[name].visible then + show_hide_button = true + break + end + end + hide_button.visible = show_hide_button - LeftFrames.new_frame(permission_name) --- Creates a new left frame define - LeftFrames._prototype:set_open_by_default(state) --- Sets if the frame is visible when a player joins, can also be a function to return a boolean - LeftFrames._prototype:set_direction(direction) --- Sets the direction of the frame, either vertical or horizontal - LeftFrames._prototype:get_frame(player) --- Gets the frame for this define from the left frame flow - LeftFrames._prototype:is_open(player) --- Returns if the player currently has this define visible - LeftFrames._prototype:toggle(player) --- Toggles the visibility of the left frame + return new_state +end - LeftFrames._prototype:update(player) --- Updates the contents of the left frame, first tries update callback, other wise will clear and redraw - LeftFrames._prototype:update_all(update_offline) --- Updates the frame for all players, see update - LeftFrames._prototype:redraw(player) --- Redraws the frame by calling on_draw, will always clear the frame - LeftFrames._prototype:redraw_all(update_offline) --- Redraws the frame for all players, see redraw +-- Draw the two flows when a player joins +Event.add(defines.events.on_player_joined_game,function(event) + local player = game.players[event.player_index] - LeftFrames._prototype:on_draw(player,frame) --- Use to draw your elements to the new frame - LeftFrames._prototype:on_update(player,frame) --- Use to edit your frame when there is no need to redraw it - LeftFrames._prototype:on_player_toggle(player,frame) --- Triggered when the player toggle the left frame - LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add -]] + -- Draw the top flow + local top_flow = Gui.get_top_flow(player) + toggle_top_flow(top_flow) + Gui.update_top_flow(player) -local CenterFrames = require 'expcore.gui.concepts.center' --- @dep expcore.gui.concepts.center -Gui.get_center_flow = CenterFrames.get_flow -Gui.toggle_center_frame = CenterFrames.toggle_frame -Gui.draw_center_frame = CenterFrames.draw_frame -Gui.redraw_center_frame = CenterFrames.redraw_frames -Gui.new_center_frame = CenterFrames.new_frame -Gui.classes.center_frames = CenterFrames ---[[ - CenterFrames.get_flow(player) --- Gets the center flow for a player - CenterFrames.clear_flow(player) --- Clears the center flow for a player - CenterFrames.draw_frame(player,name) --- Draws the center frame for a player, if already open then will do nothing - CenterFrames.redraw_frame(player,name) --- Draws the center frame for a player, if already open then will destroy it and redraw - CenterFrames.toggle_frame(player,name,state) --- Toggles if the frame is currently open or not, will open if closed and close if open + -- Draw the left flow + local left_flow = Gui.get_left_flow(player) + local hide_left = hide_left_flow(left_flow) - CenterFrames.new_frame(permission_name) --- Sets the frame to be the current active gui when opened and closes all other frames - CenterFrames._prototype:on_draw(player,frame) --- Use to draw your elements onto the new frame - CenterFrames._prototype:set_auto_focus(state) --- Sets the frame to be the current active gui when opened and closes all other frames - CenterFrames._prototype:draw_frame(player) --- Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame) - CenterFrames._prototype:redraw_frame(player) --- Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame) - CenterFrames._prototype:toggle_frame(player) --- Toggles if the frame is open, if open it will close it and if closed it will open it - CenterFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add -]] + -- Draw the elements on the left flow + local show_hide_left = false + for name,open_on_join in pairs(Gui.left_elements) do + local left_element = Gui.defines[name](left_flow) -local PopupFrames = require 'expcore.gui.concepts.popups' --- @dep expcore.gui.concepts.popups -Gui.get_popup_flow = PopupFrames.get_flow -Gui.open_popup = PopupFrames.open -Gui.new_popup = PopupFrames.new_popup -Gui.classes.popup_frames = PopupFrames ---[[ - PopupFrames.get_flow(player) --- Gets the left flow that contains the popup frames - PopupFrames.open(define_name,player,open_time,...) --- Opens a popup for the player, can give the amount of time it is open as well as params for the draw function + -- Check if the element should be visible + local visible = type(open_on_join) == 'boolean' and open_on_join or false + if type(open_on_join) == 'function' then + local success, err = pcall(open_on_join,player) + if not success then + error('There as been an error with an open on join hander for a gui element:\n\t'..err) + end + visible = err + end - PopupFrames.close_progress --- Progress bar which when depleted will close the popup frame - PopupFrames.close_button --- A button which can be used to close the gui before the timer runs out + left_element.visible = visible + if visible then + show_hide_left = true + end + end - PopupFrames.new_popup(name) --- Creates a new popup frame define - PopupFrames._prototype:set_default_open_time(amount) --- Sets the default open time for the popup, will be used if non is provided with open - PopupFrames._prototype:open(player,open_time,...) --- Opens this define for a player, can be given open time and any other params for the draw function -]] + hide_left.visible = show_hide_left +end) return Gui \ No newline at end of file diff --git a/expcore/gui/concepts/center.lua b/expcore/gui/concepts/center.lua deleted file mode 100644 index ffbc3f9f..00000000 --- a/expcore/gui/concepts/center.lua +++ /dev/null @@ -1,198 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Center Guis. --- Gui structure define for center gui frames --- @section center - ---[[ ->>>> Functions - CenterFrames.get_flow(player) --- Gets the center flow for a player - CenterFrames.clear_flow(player) --- Clears the center flow for a player - CenterFrames.draw_frame(player,name) --- Draws the center frame for a player, if already open then will do nothing - CenterFrames.redraw_frame(player,name) --- Draws the center frame for a player, if already open then will destroy it and redraw - CenterFrames.toggle_frame(player,name,state) --- Toggles if the frame is currently open or not, will open if closed and close if open - - CenterFrames.new_frame(permission_name) --- Sets the frame to be the current active gui when opened and closes all other frames - CenterFrames._prototype:on_draw(player,frame) --- Use to draw your elements onto the new frame - CenterFrames._prototype:set_auto_focus(state) --- Sets the frame to be the current active gui when opened and closes all other frames - CenterFrames._prototype:draw_frame(player) --- Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame) - CenterFrames._prototype:redraw_frame(player) --- Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame) - CenterFrames._prototype:toggle_frame(player) --- Toggles if the frame is open, if open it will close it and if closed it will open it - CenterFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Toolbar = require 'expcore.gui.concepts.toolbar' --- @dep expcore.gui.concepts.toolbar -local Game = require 'utils.game' --- @dep utils.game - -local CenterFrames = { - _prototype = Prototype.extend{ - on_creation = Prototype.event - } -} - ---- Gets the center flow for a player --- @tparam LuaPlayer player the player to get the flow for --- @treturn LuaGuiElement the center flow -function CenterFrames.get_flow(player) - player = Game.get_player_from_any(player) - return player.gui.center -end - ---- Clears the center flow for a player --- @tparam LuaPlayer player the player to clear the flow for -function CenterFrames.clear_flow(player) - local flow = CenterFrames.get_flow(player) - flow.clear() -end - ---- Draws the center frame for a player, if already open then will do nothing --- @tparam LuaPlayer player the player that will have the frame drawn --- @tparam string name the name of the hui that will drawn --- @treturn LuaGuiElement the new frame that was made -function CenterFrames.draw_frame(player,name) - local define = Gui.get_define(name,true) - if define then - return define:draw_frame(player) - end -end - ---- Draws the center frame for a player, if already open then will destroy it and redraw --- @tparam LuaPlayer player the player that will have the frame drawn --- @tparam string name the name of the hui that will drawn --- @treturn LuaGuiElement the new frame that was made -function CenterFrames.redraw_frame(player,name) - local define = Gui.get_define(name,true) - if define then - return define:draw_frame(player) - end -end - ---- Toggles if the frame is currently open or not, will open if closed and close if open --- @tparam LuaPlayer player the player that will have the frame toggled --- @tparam string name the name of the hui that will be toggled --- @tparam[opt] boolean state when set will force a state for the frame --- @treturn boolean if the frame if no open or closed -function CenterFrames.toggle_frame(player,name,state) - local define = Gui.get_define(name,true) - if define then - if state == true then - define:draw_frame(player) - return true - elseif state == false then - local flow = CenterFrames.get_flow(player) - if flow[define.name..'-frame'] then - flow[define.name..'-frame'].destroy() - end - return false - else - return define:toggle_frame(player) - end - end -end - ---- Creates a new center frame define --- @tparam string permission_name the name that can be used with the permission system --- @treturn table the new center frame define -function CenterFrames.new_frame(permission_name) - local self = Toolbar.new_button(permission_name) - - self:on_click(function(player,element) - self:toggle_frame(player) - end) - - local mt = getmetatable(self) - mt.__index = CenterFrames._prototype - mt.__call = self.event_handler - - Gui.on_custom_close(self.name..'-frame',function(event) - local element = event.element - if element and element.valid then element.destroy() end - end) - - return self -end - ---- Sets the frame to be the current active gui when opened and closes all other frames --- @tparam[opt=true] boolean state when true will auto close other frames and set this frame as player.opened -function CenterFrames._prototype:set_auto_focus(state) - if state == false then - self.auto_focus = false - else - self.auto_focus = true - end -end - ---- Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame) --- @tparam LuaPlayer player the player to draw the frame for --- @treturn LuaGuiElement the new frame that was drawn -function CenterFrames._prototype:draw_frame(player) - player = Game.get_player_from_any(player) - local flow = CenterFrames.get_flow(player) - - if flow[self.name..'-frame'] then - return flow[self.name..'-frame'] - end - - if self.auto_focus then - flow.clear() - end - - local frame = flow.add{ - type='frame', - name=self.name..'-frame' - } - - if self.auto_focus then - player.opened = frame - end - - self:raise_event('on_creation',player,frame) - - return frame -end - ---- Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame) --- @tparam LuaPlayer player the player to draw the frame for --- @treturn LuaGuiElement the new frame that was drawn -function CenterFrames._prototype:redraw_frame(player) - player = Game.get_player_from_any(player) - local flow = CenterFrames.get_flow(player) - - if flow[self.name..'-frame'] then - flow[self.name..'-frame'].destroy() - end - - return self:draw_frame(player) -end - ---- Toggles if the frame is open, if open it will close it and if closed it will open it --- @tparam LuaPlayer player the player to draw the frame for --- @treturn boolean with the gui frame is now open -function CenterFrames._prototype:toggle_frame(player) - player = Game.get_player_from_any(player) - local flow = CenterFrames.get_flow(player) - - if flow[self.name..'-frame'] then - flow[self.name..'-frame'].destroy() - return false - else - self:draw_frame(player) - return true - end -end - ---- Creates an event handler that will trigger one of its functions, use with Event.add --- @tparam[opt=update] string action the action to take on this event -function CenterFrames._prototype:event_handler(action) - action = action or 'update' - return function(event) - local player = Game.get_player_by_index(event.player_index) - self[action](self,player) - end -end - -return CenterFrames \ No newline at end of file diff --git a/expcore/gui/concepts/left.lua b/expcore/gui/concepts/left.lua deleted file mode 100644 index e827f36a..00000000 --- a/expcore/gui/concepts/left.lua +++ /dev/null @@ -1,322 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Left Guis. --- Gui structure define for left frames --- @section left - ---[[ ->>>> Example formating - - -- first we add config that relates to the button on the toolbar, all normal button functions are present - local left_frame = - Gui.new_left_frame('test-left-frame') - :set_caption('Test Left Gui') - :set_post_authenticator(function(player,button_name) - return global.show_test_gui - end) - - -- then we add the config for the left frame, on_draw should draw the gui from an empty frame, on_update should take a frame from on_draw on edit it - :set_open_by_default() - :on_draw(function(_player,frame) - for _,player in pairs(game.connected_players) do - frame.add{ - type='label', - caption=player.name - } - end - end) - - -- now we can use the action factory to call events on the gui, actions are: 'update', 'update_all', 'redraw', 'redraw_all' - Event.add(defines.events.on_player_joined_game,left_frame 'update_all') - Event.add(defines.events.on_player_left_game,left_frame 'update_all') - ->>>> Functions - LeftFrames.get_flow(player) --- Gets the left frame flow for a player - LeftFrames.get_frame(name,player) --- Gets one frame from the left flow by its name - LeftFrames.get_open(player) --- Gets all open frames for a player, if non are open it will remove the close all button - LeftFrames.toggle_frame(name,player,state) --- Toggles the visibility of a left frame, or sets its visibility state - - LeftFrames.new_frame(permission_name) --- Creates a new left frame define - LeftFrames._prototype:set_open_by_default(state) --- Sets if the frame is visible when a player joins, can also be a function to return a boolean - LeftFrames._prototype:set_direction(direction) --- Sets the direction of the frame, either vertical or horizontal - LeftFrames._prototype:get_frame(player) --- Gets the frame for this define from the left frame flow - LeftFrames._prototype:is_open(player) --- Returns if the player currently has this define visible - LeftFrames._prototype:toggle(player) --- Toggles the visibility of the left frame - - LeftFrames._prototype:update(player) --- Updates the contents of the left frame, first tries update callback, other wise will clear and redraw - LeftFrames._prototype:update_all(update_offline) --- Updates the frame for all players, see update - LeftFrames._prototype:redraw(player) --- Redraws the frame by calling on_draw, will always clear the frame - LeftFrames._prototype:redraw_all(update_offline) --- Redraws the frame for all players, see redraw - - LeftFrames._prototype:on_draw(player,frame) --- Use to draw your elements to the new frame - LeftFrames._prototype:on_update(player,frame) --- Use to edit your frame when there is no need to redraw it - LeftFrames._prototype:on_player_toggle(player,frame) --- Is triggered when the player presses the toggle button - LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Toolbar = require 'expcore.gui.concepts.toolbar' --- @dep expcore.gui.concepts.toolbar -local Buttons = require 'expcore.gui.elements.buttons' --- @dep expcore.gui.elements.buttons -local mod_gui = require 'mod-gui' --- @dep mod-gui -local Game = require 'utils.game' --- @dep utils.game -local Event = require 'utils.event' --- @dep utils.event - -local LeftFrames = { - frames={}, - _prototype=Prototype.extend{ - on_creation = Prototype.event, - on_update = Prototype.event, - on_player_toggle = Prototype.event - } -} -setmetatable(LeftFrames._prototype, { - __index = Buttons._prototype -}) - ---- Gets the left frame flow for a player --- @tparam LuaPlayer player the player to get the flow of --- @treturn LuaGuiElement the left frame flow for the player -function LeftFrames.get_flow(player) - player = Game.get_player_from_any(player) - return mod_gui.get_frame_flow(player) -end - ---- Gets one frame from the left flow by its name --- @tparam string name the name of the gui frame to get --- @tparam LuaPlayer player the player to get the frame of --- @treturn LuaGuiElement the frame in the left frame flow with that name -function LeftFrames.get_frame(name,player) - local define = LeftFrames.frames[name] - if not define then - return error('Left Frame '..name..' is not defined.',2) - end - return define:get_frame(player) -end - ---- Gets all open frames for a player, if non are open it will remove the close all button --- @tparam LuaPlayer player the player to get the flow of --- @treturn table contains all the open (and registered) frames for the player -function LeftFrames.get_open(player) - local open = {} - local flow = LeftFrames.get_flow(player) - - for _,define in pairs(LeftFrames.frames) do - if define:is_open(player) then - table.insert(open,define) - end - end - - flow[LeftFrames.toggle_button.name].visible = #open ~= 0 - - return open -end - ---- Toggles the visibility of a left frame, or sets its visibility state --- @tparam string name the name of the gui frame to toggle --- @tparam LuaPlayer player the player to get the frame of --- @tparam[opt] boolean state when given will be the state that the visibility is set to --- @treturn boolean the new state of the visibility -function LeftFrames.toggle_frame(name,player,state) - local define = LeftFrames.frames[name] - if not define then - return error('Left Frame '..name..' is not defined.',2) - end - - local frame = LeftFrames.get_frame(name,player) - if state ~= nil then - frame.visible = state - else - Gui.toggle_visible(frame) - end - - LeftFrames.get_open(player) - - return frame.visible -end - ---- Creates a new left frame define --- @tparam string permission_name the name that can be used with the permission system --- @treturn table the new left frame define -function LeftFrames.new_frame(permission_name) - local self = Toolbar.new_button(permission_name) - - local mt = getmetatable(self) - mt.__index = LeftFrames._prototype - mt.__call = self.event_handler - - self:on_click(function(player,_element) - local visible = self:toggle(player) - local frame = self:get_frame(player) - self:raise_event('on_player_toggle',player,frame,visible) - end) - - LeftFrames.frames[self.name] = self - - return self -end - ---- Sets if the frame is visible when a player joins, can also be a function to return a boolean --- @tparam[opt=true] ?boolean|function state the default state of the visibility, can be a function --- state param - player LuaPlayer - the player that has joined the game --- state param - define_name string - the define name for the frame --- state return - boolean - false will hide the frame -function LeftFrames._prototype:set_open_by_default(state) - if state == false then - self.open_by_default = false - elseif state == nil then - self.open_by_default = true - else - self.open_by_default = state - end - return self -end - ---- Sets the direction of the frame, either vertical or horizontal --- @tparam string direction the direction to have the elements be added to the frame -function LeftFrames._prototype:set_direction(direction) - self.direction = direction - return self -end - ---- Creates the gui for the first time, used internally --- @tparam LuaPlayer player the player to draw the frame to --- @treturn LuaGuiElement the frame that was made -function LeftFrames._prototype:_internal_draw(player) - local flow = LeftFrames.get_flow(player) - local frame = flow.add{ - type='frame', - name=self.name..'-frame', - direction=self.direction - } - - self:raise_event('on_creation',player,frame) - - if not self.open_by_default then - frame.visible = false - elseif type(self.open_by_default) == 'function' then - if not self.open_by_default(player,self.name) then - frame.visible = false - end - end - - if not Toolbar.allowed(player,self.name) then - frame.visible = false - end - - return frame -end - ---- Gets the frame for this define from the left frame flow --- @tparam LuaPlayer player the player to get the frame of --- @treturn LuaGuiElement the frame in the left frame flow for this define -function LeftFrames._prototype:get_frame(player) - local flow = LeftFrames.get_flow(player) - if flow[self.name..'-frame'] and flow[self.name..'-frame'].valid then - return flow[self.name..'-frame'] - else - return self:_internal_draw(player) - end -end - ---- Returns if the player currently has this define visible --- @tparam LuaPlayer player the player to get the frame of --- @treturn boolean true if it is open/visible -function LeftFrames._prototype:is_open(player) - local frame = self:get_frame(player) - return frame and frame.visible or false -end - ---- Toggles the visibility of the left frame --- @tparam LuaPlayer player the player to toggle the frame of --- @treturn boolean the new state of the visibility -function LeftFrames._prototype:toggle(player) - local frame = self:get_frame(player) - Gui.toggle_visible(frame) - LeftFrames.get_open(player) - return frame.visible -end - ---- Updates the contents of the left frame, first tries update callback, other wise will clear and redraw --- @tparam LuaPlayer player the player to update the frame of -function LeftFrames._prototype:update(player) - local frame = self:get_frame(player) - if self:raise_event('on_update',player,frame) == 0 then - frame.clear() - self:raise_event('on_creation',player,frame) - end -end - ---- Updates the frame for all players, see update --- @tparam[opt=false] boolean update_offline when true will update the frame for offline players -function LeftFrames._prototype:update_all(update_offline) - local players = update_offline == true and game.players or game.connected_players - for _,player in pairs(players) do - self:update(player) - end -end - ---- Redraws the frame by calling on_draw, will always clear the frame --- @tparam LuaPlayer player the player to update the frame of -function LeftFrames._prototype:redraw(player) - local frame = self:get_frame(player) - frame.clear() - self:raise_event('on_creation',player,frame) -end - ---- Redraws the frame for all players, see redraw --- @tparam[opt=false] boolean update_offline when true will update the frame for offline players -function LeftFrames._prototype:redraw_all(update_offline) - local players = update_offline == true and game.players or game.connected_players - for _,player in pairs(players) do - self:redraw(player) - end -end - ---- Creates an event handler that will trigger one of its functions, use with Event.add --- @tparam[opt=update] string action the action to take on this event -function LeftFrames._prototype:event_handler(action) - action = action or 'update' - return function(event) - local player - if event and event.player_index then - player = Game.get_player_by_index(event.player_index) - end - self[action](self,player) - end -end - -LeftFrames.toggle_button = -Buttons.new_button() -:set_tooltip{'expcore-gui.left-button-tooltip'} -:set_caption('<') -:on_click(function(player,element) - for _,define in pairs(LeftFrames.frames) do - local frame = LeftFrames.get_frame(define.name,player) - frame.visible = false - define:raise_event('on_player_toggle',player,frame,false) - end - element.visible = false -end) - -Event.add(defines.events.on_player_created,function(event) - local player = Game.get_player_by_index(event.player_index) - local flow = LeftFrames.get_flow(player) - - local close_button = LeftFrames.toggle_button(flow) - Gui.set_padding(close_button) - local style = close_button.style - style.width = 18 - style.height = 36 - style.font = 'default-small-bold' - - for _,define in pairs(LeftFrames.frames) do - define:_internal_draw(player) - end - - LeftFrames.get_open(player) -end) - -return LeftFrames \ No newline at end of file diff --git a/expcore/gui/concepts/popups.lua b/expcore/gui/concepts/popups.lua deleted file mode 100644 index bda932b3..00000000 --- a/expcore/gui/concepts/popups.lua +++ /dev/null @@ -1,230 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Popups. --- Gui structure define for popup gui --- @section popups - ---[[ ->>>> Functions - PopupFrames.get_flow(player) --- Gets the left flow that contains the popup frames - PopupFrames.open(define_name,player,open_time,...) --- Opens a popup for the player, can give the amount of time it is open as well as params for the draw function - - PopupFrames.close_progress --- Progress bar which when depleted will close the popup frame - PopupFrames.close_button --- A button which can be used to close the gui before the timer runs out - - PopupFrames.new_popup(name) --- Creates a new popup frame define - PopupFrames._prototype:set_default_open_time(amount) --- Sets the default open time for the popup, will be used if non is provided with open - PopupFrames._prototype:open(player,open_time,...) --- Opens this define for a player, can be given open time and any other params for the draw function -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Game = require 'utils.game' --- @dep utils.game -local Event = require 'utils.event' --- @dep utils.event -local ProgressBar = require 'expcore.gui.elements.progress-bar' --- @dep expcore.gui.elements.progress-bar -local Button = require 'expcore.gui.elements.buttons' --- @dep expcore.gui.elements.buttons -local mod_gui = require 'mod-gui' --- @dep mod-gui -local Color = require 'resources.color_presets' --- @dep resources.color_presets -local Global = require 'utils.global' --- @dep utils.global - -local PopupFrames = { - paused_popups={}, - popup_flow_name = Gui.uid_name(), - main_frame_name = Gui.uid_name(), - close_frame_name = Gui.uid_name(), - _prototype = Prototype.extend{ - on_creation = Prototype.event - } -} -Global.register(PopupFrames.paused_popups,function(tbl) - PopupFrames.paused_popups = tbl -end) - ---- Sets the state of the element in the paused list, nil or true --- @tparam LuaGuiElement element the element to set the state of --- @tparam[opt] boolean state the state to set it to, true will pause the the progress bar -local function set_paused_state(element,state) - local name = element.player_index..':'..element.index - PopupFrames.paused_popups[name] = state -end - ---- Gets the state of the element in the paused list, nil or true --- @tparam LuaGuiElement element the element to get the state of -local function get_paused_state(element) - local name = element.player_index..':'..element.index - return PopupFrames.paused_popups[name] -end - ---- Gets the left flow that contains the popup frames --- @tparam LuaPlayer player the player to get the flow for --- @treturn LuaGuiElement the left flow that contains the popup frames -function PopupFrames.get_flow(player) - player = Game.get_player_from_any(player) - local flow = mod_gui.get_frame_flow(player) - return flow[PopupFrames.popup_flow_name] -end - ---- Opens a popup for the player, can give the amount of time it is open as well as params for the draw function --- @tparam string define_name the name of the define that you want to open for the player --- @tparam LuaPlayer player the player to open the popup for --- @tparam[opt] number open_time the minimum number of ticks you want the popup open for, 0 means no limit, nil will take default --- @tparam any ... the other params that you want to pass to your on_draw event --- @treturn LuaGuiElement the frame that was drawn, the inner gui flow which contains the content -function PopupFrames.open(define_name,player,open_time,...) - local define = Gui.get_define(define_name,true) - player = Game.get_player_from_any(player) - return define:open(player,open_time,...) -end - ---- Closes the popup, is called by progress bar and close button --- @tparam LuaGuiElement element either the progress bar or the close button -local function close_popup(element) - local frame = element.parent.parent.parent - if not frame or not frame.valid then return end - set_paused_state(element.parent[PopupFrames.close_progress:uid()]) - frame.destroy() -end - ---- Progress bar which when depleted will close the popup frame -PopupFrames.close_progress = -ProgressBar.new_progressbar() -:use_count_down() -:set_tooltip('Pause/Resume Auto-close') -:on_complete(function(player,element) - close_popup(element) -end) - ---- A button which can be used to close the gui before the timer runs out -PopupFrames.close_button = -Button.new_button() -:set_sprites('utility/close_white') -:set_tooltip('Close Popup') -:on_click(function(player,element) - close_popup(element) -end) - ---- When the progress bar is clicked it will pause its progress, or resume if previously paused -Gui.on_click(PopupFrames.close_progress:uid(),function(event) - local element = event.element - if get_paused_state(element) then - set_paused_state(element) - else - set_paused_state(element,true) - end -end) - ---- When the parent flow of the progress bar is clicked it will pause its progress, or resume if previously paused -Gui.on_click(PopupFrames.close_frame_name,function(event) - local element = event.element[PopupFrames.close_progress:uid()] - if get_paused_state(element) then - set_paused_state(element) - else - set_paused_state(element,true) - end -end) - ---- Creates a new popup frame define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new popup frame define -function PopupFrames.new_popup(name) - local self = Gui.new_define(PopupFrames._prototype,name) - self.draw_data.type = 'flow' - self.draw_data.direction = 'vertical' - - local mt = getmetatable(self) - mt.__call = function(tbl,player,open_time,...) - return tbl:open(player,open_time,...) - end - - self:on_draw(function(player,element,maximum,...) - -- main content frame - local frame = element.add{ - type='flow', - name=PopupFrames.main_frame_name - } - frame.style.horizontally_stretchable = true - - -- flow for progress bar and close button - local close_flow = element.add{ - type='flow', - name=PopupFrames.close_frame_name - } - close_flow.style.horizontally_stretchable = true - - -- progress bar, when 0 then a static full one is drawn - local progress_style - if maximum == 0 then - progress_style = close_flow.add{ - type='progressbar', - tooltip='No Auto-close', - value=1 - }.style - else - progress_style = PopupFrames.close_progress(close_flow,maximum).style - end - progress_style.top_padding = 6 - progress_style.bottom_padding = 3 - progress_style.height = 11 - progress_style.color = Color.grey - - -- close button, will close the popup when clicked - local close_button = PopupFrames.close_button(close_flow) - Gui.set_padding(close_button) - local close_button_style = close_button.style - close_button_style.width = 20 - close_button_style.height = 20 - - -- event trigger to draw the gui content - self:raise_event('on_creation',player,frame,...) - end) - - return self -end - ---- Sets the default open time for the popup, will be used if non is provided with open --- @tparam number amount the number of ticks, by default, the popup will be open for --- @treturn table the define to allow for chaining -function PopupFrames._prototype:set_default_open_time(amount) - self.default_open_time = amount - return self -end - ---- Opens this define for a player, can be given open time and any other params for the draw function --- @tparam LuaPlayer player the player to open the popup for --- @tparam[opt] number open_time the minimum number of ticks you want the popup open for, 0 means no limit, nil will take default --- @tparam any ... the other params that you want to pass to your on_draw event --- @treturn LuaGuiElement the frame that was drawn, the inner gui flow which contains the content -function PopupFrames._prototype:open(player,open_time,...) - open_time = open_time or self.default_open_time or 0 - player = Game.get_player_from_any(player) - - local flow = PopupFrames.get_flow(player) - local frame = flow.add{ - type='frame', - style='blurry_frame' - } - - Gui.set_padding(frame,3,3,4,4) - return self:draw_to(frame,open_time,...)[PopupFrames.main_frame_name] -end - ---- When player is first created the popup flow is added to they left flow -Event.add(defines.events.on_player_created,function(event) - local player = Game.get_player_by_index(event.player_index) - local flow = mod_gui.get_frame_flow(player) - - flow.add{ - type='flow', - direction='vertical', - name=PopupFrames.popup_flow_name - } -end) - ---- Every tick any, not paused, progress bars will go down by one tick -Event.add(defines.events.on_tick,PopupFrames.close_progress:event_countdown(function(element) - return not get_paused_state(element) -end)) - -return PopupFrames \ No newline at end of file diff --git a/expcore/gui/concepts/toolbar.lua b/expcore/gui/concepts/toolbar.lua deleted file mode 100644 index 10a8d971..00000000 --- a/expcore/gui/concepts/toolbar.lua +++ /dev/null @@ -1,114 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Toolbar. --- Gui structure for the toolbar (top left) --- @section toolbar - ---[[ ->>>> Example format - -- this is the same as any other button define, this just automatically draws it - -- you can use add_button if you already defined the button - local toolbar_button = - Toolbar.new_button('print-click') - :on_click(function(player,_element) - player.print('You clicked a button!') - end) - ->>>> Functions - Toolbar.new_button(name) --- Adds a new button to the toolbar - Toolbar.add_button(button) --- Adds an existing buttton to the toolbar - Toolbar.update(player) --- Updates the player's toolbar with an new buttons or expected change in auth return -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Buttons = require 'expcore.gui.elements.buttons' --- @dep expcore.gui.elements.buttons -local Roles = require 'expcore.roles' --- @dep expcore.roles -local Event = require 'utils.event' --- @dep utils.event -local Game = require 'utils.game' --- @dep utils.game -local mod_gui = require 'mod-gui' --- @dep mod-gui - -local Toolbar = { - permission_names = {}, - buttons = {} -} - -function Toolbar.allowed(player,define_name) - local permission_name = Toolbar.permission_names[define_name] or define_name - return Roles.player_allowed(player,permission_name) -end - -function Toolbar.permission_alias(define_name,permission_name) - Toolbar.permission_names[define_name] = permission_name -end - ---- Adds a new button to the toolbar --- @tparam[opt] string name when given allows an alias to the button for the permission system --- @treturn table the button define -function Toolbar.new_button(name) - local button = - Buttons.new_button() - :set_post_authenticator(Toolbar.allowed) - :set_style(mod_gui.button_style,function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - end) - Toolbar.add_button(button) - Toolbar.permission_alias(button.name,name) - return button -end - ---- Adds an existing buttton to the toolbar --- @tparam table button the button define for the button to be added -function Toolbar.add_button(button) - table.insert(Toolbar.buttons,button) - Gui.allow_player_to_toggle_top_element_visibility(button.name) - Gui.on_player_show_top(button.name,function(event) - if not button.post_authenticator(event.player,button.name) then - event.element.visible = false - end - end) - if not button.post_authenticator then - button:set_post_authenticator(function() return true end) - end -end - ---- Updates the player's toolbar with an new buttons or expected change in auth return --- @tparam LuaPlayer player the player to update the toolbar for -function Toolbar.update(player) - local top = Gui.get_top_element_flow(player) - if not top then return end - local visible = top[Gui.top_toggle_button_name].caption == '<' - for _,button in pairs(Toolbar.buttons) do - local element - if top[button.name] then element = top[button.name] - else element = button:draw_to(top) end - if button.post_authenticator(player,button.name) then - element.visible = visible - element.enabled = true - else - element.visible = false - element.enabled = false - end - end -end - ---- When there is a new player they will have the toolbar update -Event.add(defines.events.on_player_created,function(event) - local player = Game.get_player_by_index(event.player_index) - Toolbar.update(player) -end) - ---- When a player gets a new role they will have the toolbar updated -Event.add(Roles.events.on_role_assigned,function(event) - local player = Game.get_player_by_index(event.player_index) - Toolbar.update(player) -end) - ---- When a player loses a role they will have the toolbar updated -Event.add(Roles.events.on_role_unassigned,function(event) - local player = Game.get_player_by_index(event.player_index) - Toolbar.update(player) -end) - -return Toolbar \ No newline at end of file diff --git a/expcore/gui/core.lua b/expcore/gui/core.lua deleted file mode 100644 index 1fd93480..00000000 --- a/expcore/gui/core.lua +++ /dev/null @@ -1,368 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Core. --- Core gui file for making element defines and element classes (use require 'expcore.gui') --- see utils.gui for event handlering --- see expcore.gui.test for examples for element defines --- @section core - ---[[ ->>>> Basic useage with no defines - This module can be igroned if you are only wanting only event handlers as utils.gui adds the following: - - Gui.uid_name() --- Generates a unqiue name to register events to - Gui.on_checked_state_changed(callback) --- Register a handler for the on_gui_checked_state_changed event - Gui.on_click(callback) --- Register a handler for the on_gui_click event - Gui.on_elem_changed(callback) --- Register a handler for the on_gui_elem_changed - Gui.on_selection_state_changed(callback) --- Register a handler for the on_gui_selection_state_changed event - Gui.on_text_changed(callback) --- Register a handler for the on_gui_text_changed event - Gui.on_value_changed(callback) --- Register a handler for the on_gui_value_changed event - - Note that all event handlers will include event.player as a valid player and that if the player or the - element is not valid then the callback will not be run. - ->>>> Basic prototype functions (see expcore.gui.prototype) - Using a class defination you can create a new element dinfation in our examples we will be using the checkbox. - - local checkbox_example = Gui.new_checkbox() - - Although all class definations are stored in Gui.classes the main function used to make new element defination are - made aviable in the top level gui module. All functions which return a new element defination will accept a name argument - which is a name which is used while debuging and is not required to be used (has not been used in examples) - - Every element define will accept a caption and tooltip (although some may not show) and to do this you would use the two - set function provided for the element defines: - - checkbox_example:set_caption('Example Checkbox') - checkbox_example:set_tooltip('Example checkbox') - - Each element define can have event handlers set, for our example checkbox we only have access to on_change which will trigger - when the state of the checkbox changes; if we want to assign handlers using the utils.gui methods then we can get the uid by calling - the uid function on the element define; however, each element can only have one handler (of each event) so it is not possible to use - Gui.on_checked_state_changed and on_change at the same time in our example. - - checkbox_example:on_change(function(player,element,value) - player.print('Example checkbox is now: '..tostring(value)) - end) - - local checkbox_example_uid = checkbox_example:uid() - Gui.on_click(checkbox_example_uid,function(event) - event.player.print('You clicked the example checkbox!') - end) - - Finally you will want to draw your element defines for which you can call deirectly on the deinfe or use Gui.draw to do; when Gui.draw is - used it can be given either the element define, the define's uid or the debug name of the define (if set): - - checkbox_example:draw_to(parent_element) - Gui.draw(checkbox_example_uid,parent_element) - ->>>> Using authenticators with draw - When an element is drawn to its parent it can always be used but if you want to limit who can use it then you can use an authenticator. There - are two types which can be used: post and pre; using a pre authenticator will mean that the draw function is stoped before the element is added - to the parent element while using a post authenticator will draw the element to the parent but will disable the element from interaction. Both may - be used if you have use for such. - - -- unless global.checkbox_example_allow_pre_auth is true then the checkbox will not be drawn - checkbox_example:set_pre_authenticator(function(player,define_name) - player.print('Example checkbox pre auth callback ran') - return global.checkbox_example_allow_pre_auth - end) - - -- unless global.checkbox_example_allow_post_auth is true then the checkbox will be drawn but deactiveated (provided pre auth returns true) - checkbox_example:set_post_authenticator(function(player,define_name) - player.print('Example checkbox pre auth callback ran') - return global.checkbox_example_allow_post_auth - end) - ->>>> Using store (see expcore.gui.prototype and expcore.gui.instances) - A powerful assept of this gui system is allowing an automatic store for the state of a gui element, this means that when a gui is closed and re-opened - the elements which have a store will retain they value even if the element was previously destroied. The store is not limited to only per player and can - be catergorised by any method you want such as one that is shared between all players or by all players on a force. Using a method that is not limited to - one player means that when one player changes the state of the element it will be automaticlly updated for all other player (even if the element is already drawn) - and so this is a powerful and easy way to sync gui elements. - - -- note the example below is the same as checkbox_example:add_store(Gui.categorize_by_player) - checkbox_example:add_store(function(element) - local player = Game.get_player_by_index(element.player_index) - return player.force.name - end) - - Of course this tool is not limited to only player interactions; the current satate of a define can be gotten using a number of methods and the value can - even be updated by the script and have all instances of the element define be updated. When you use a category then we must give a category to the get - and set functions; in our case we used Gui.categorize_by_player which uses the player's name as the category which is why 'Cooldude2606' is given as a argument, - if we did not set a function for add_store then all instances for all players have the same value and so a category is not required. - - checkbox_example:get_store('Cooldude2606') - Gui.get_store(name,'Cooldude2606') - - checkbox_example:set_store('Cooldude2606',true) - Gui.set_store(name,'Cooldude2606',true) - - These methods use the Store module which means that if you have the need to access these sotre location (for example if you want to add a watch function) then - you can get the store location of any define using checkbox_example.store - - Important note about event handlers: when the store is updated it will also trigger the event handlers (such as on_element_update) for that define but only - for the valid instances of the define which means if a player does not have the element drawn on a gui then it will not trigger the events; if you want a - trigger for all updates then you can use on_store_update however you will be required to parse the category which may or may not be a - player name (depends what store categorize function you use) - ->>>> Example formating - - local checkbox_example = - Gui.new_checkbox() - :set_caption('Example Checkbox') - :set_tooltip('Example checkbox') - :add_store(Gui.categorize_by_player) - :on_element_update(function(player,element,value) - player.print('Example checkbox is now: '..tostring(value)) - end) - ->>>> Functions - Gui.new_define(prototype) --- Used internally to create new element defines from a class prototype - Gui.draw(name,element) --- Draws a copy of the element define to the parent element, see draw_to - - Gui.categorize_by_player(element) --- A categorize function to be used with add_store, each player has their own value - Gui.categorize_by_force(element) --- A categorize function to be used with add_store, each force has its own value - Gui.categorize_by_surface(element) --- A categorize function to be used with add_store, each surface has its own value - - Gui.toggle_enabled(element) --- Will toggle the enabled state of an element - Gui.toggle_visible(element) --- Will toggle the visiblity of an element - Gui.set_padding(element,up,down,left,right) --- Sets the padding for a gui element - Gui.set_padding_style(style,up,down,left,right) --- Sets the padding for a gui style - Gui.create_alignment(element,flow_name) --- Allows the creation of a right align flow to place elements into - Gui.destroy_if_valid(element) --- Destroies an element but tests for it being present and valid first - Gui.create_scroll_table(element,table_size,maximal_height,name) --- Creates a scroll area with a table inside, table can be any size - Gui.create_header(element,caption,tooltip,right_align,name) --- Creates a header section with a label and button area -]] -local Gui = require 'utils.gui' --- @dep utils.gui -local Game = require 'utils.game' --- @dep utils.game - -Gui.classes = {} -- Stores the class definations used to create element defines -Gui.defines = {} -- Stores the indivdual element definations -Gui.names = {} -- Stores debug names to link to gui uids - ---- Used to create new element defines from a class prototype, please use the own given by the class --- @tparam table prototype the class prototype that will be used for the element define --- @tparam[opt] string debug_name the name that you want to see while debuging --- @treturn table the new element define with all functions accessed via __index metamethod -function Gui.new_define(prototype,debug_name) - local name = Gui.uid_name() - local define = setmetatable({ - debug_name = debug_name, - name = name, - events = {}, - draw_data = { - name = name - } - },{ - __index = prototype, - __call = function(self,...) - return self:draw_to(...) - end - }) - Gui.defines[define.name] = define - return define -end - ---- Gets an element define give the uid, debug name or a copy of the element define --- @tparam ?string|table name the uid, debug name or define for the element define to get --- @tparam[opt] boolean internal when true the error trace is one level higher (used internally) --- @treturn table the element define that was found or an error -function Gui.get_define(name,internal) - if type(name) == 'table' then - if name.name and Gui.defines[name.name] then - return Gui.defines[name.name] - end - end - - local define = Gui.defines[name] - - if not define and Gui.names[name] then - return Gui.defines[Gui.names[name]] - - elseif not define then - return error('Invalid name for element define, name not found.',internal and 3 or 2) or nil - - end - - return define -end - ---- A categorize function to be used with add_store, each player has their own value --- @tparam LuaGuiElement element the element that will be converted to a string --- @treturn string the player's name who owns this element -function Gui.categorize_by_player(element) - local player = Game.get_player_by_index(element.player_index) - return player.name -end - ---- A categorize function to be used with add_store, each force has its own value --- @tparam LuaGuiElement element the element that will be converted to a string --- @treturn string the player's force name who owns this element -function Gui.categorize_by_force(element) - local player = Game.get_player_by_index(element.player_index) - return player.force.name -end - ---- A categorize function to be used with add_store, each surface has its own value --- @tparam LuaGuiElement element the element that will be converted to a string --- @treturn string the player's surface name who owns this element -function Gui.categorize_by_surface(element) - local player = Game.get_player_by_index(element.player_index) - return player.surface.name -end - ---- Draws a copy of the element define to the parent element, see draw_to --- @tparam ?string|table name the uid, debug name or define for the element define to draw --- @tparam LuaGuiEelement element the parent element that it the define will be drawn to --- @treturn LuaGuiElement the new element that was created -function Gui.draw(name,element,...) - local define = Gui.get_define(name,true) - return define:draw_to(element,...) -end - ---- Will toggle the enabled state of an element --- @tparam LuaGuiElement element the gui element to toggle --- @treturn boolean the new state that the element has -function Gui.toggle_enabled(element) - if not element or not element.valid then return end - if not element.enabled then - element.enabled = true - else - element.enabled = false - end - return element.enabled -end - ---- Will toggle the visiblity of an element --- @tparam LuaGuiElement element the gui element to toggle --- @treturn boolean the new state that the element has -function Gui.toggle_visible(element) - if not element or not element.valid then return end - if not element.visible then - element.visible = true - else - element.visible = false - end - return element.visible -end - ---- Sets the padding for a gui element --- @tparam LuaGuiElement element the element to set the padding for --- @tparam[opt=0] number up the amount of padding on the top --- @tparam[opt=0] number down the amount of padding on the bottom --- @tparam[opt=0] number left the amount of padding on the left --- @tparam[opt=0] number right the amount of padding on the right -function Gui.set_padding(element,up,down,left,right) - local style = element.style - style.top_padding = up or 0 - style.bottom_padding = down or 0 - style.left_padding = left or 0 - style.right_padding = right or 0 -end - ---- Sets the padding for a gui style --- @tparam LuaStyle style the element to set the padding for --- @tparam[opt=0] number up the amount of padding on the top --- @tparam[opt=0] number down the amount of padding on the bottom --- @tparam[opt=0] number left the amount of padding on the left --- @tparam[opt=0] number right the amount of padding on the right -function Gui.set_padding_style(style,up,down,left,right) - style.top_padding = up or 0 - style.bottom_padding = down or 0 - style.left_padding = left or 0 - style.right_padding = right or 0 -end - ---- Allows the creation of an alignment flow to place elements into --- @tparam LuaGuiElement element the element to add this alignment into --- @tparam[opt] string name the name to use for the alignment --- @tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in this flow --- @tparam[opt='center'] string vertical_align the vertical alignment of the elements in this flow --- @treturn LuaGuiElement the new flow that was created -function Gui.create_alignment(element,name,horizontal_align,vertical_align) - local flow = element.add{name=name,type='flow'} - local style = flow.style - Gui.set_padding(flow,1,1,2,2) - style.horizontal_align = horizontal_align or 'right' - style.vertical_align = vertical_align or 'center' - style.horizontally_stretchable =style.horizontal_align ~= 'center' - style.vertically_stretchable = style.vertical_align ~= 'center' - return flow -end - ---- Destroies an element but tests for it being present and valid first --- @tparam LuaGuiElement element the element to be destroied --- @treturn boolean true if it was destoried -function Gui.destroy_if_valid(element) - if element and element.valid then - element.destroy() - return true - end -end - ---- Creates a scroll area with a table inside, table can be any size --- @tparam LuaGuiElement element the element to add this scroll into --- @tparam number table_size the number of columns in the table --- @tparam number maximal_height the max hieght of the scroll --- @tparam[opt='scroll'] string name the name of the scoll element --- @treturn LuaGuiElement the table that was made -function Gui.create_scroll_table(element,table_size,maximal_height,name) - local list_scroll = - element.add{ - name=name or 'scroll', - type='scroll-pane', - direction='vertical', - horizontal_scroll_policy='never', - vertical_scroll_policy='auto-and-reserve-space' - } - Gui.set_padding(list_scroll,1,1,2,2) - list_scroll.style.horizontally_stretchable = true - list_scroll.style.maximal_height = maximal_height - - local list_table = - list_scroll.add{ - name='table', - type='table', - column_count=table_size - } - Gui.set_padding(list_table) - list_table.style.horizontally_stretchable = true - list_table.style.vertical_align = 'center' - list_table.style.cell_padding = 0 - - return list_table -end - ---- Creates a header section with a label and button area --- @tparam LuaGuiElement element the element to add this header into --- @tparam localeString caption the caption that is used as the title --- @tparam[opt] localeString tooltip the tooltip that is shown on the caption --- @tparam[opt] boolean right_align when true will include the right align area --- @tparam[opt='header'] string name the name of the header area --- @treturn LuaGuiElement the header that was made, or the align area if that was created -function Gui.create_header(element,caption,tooltip,right_align,name) - local header = - element.add{ - name=name or 'header', - type='frame', - style='subheader_frame' - } - Gui.set_padding(header,2,2,4,4) - header.style.horizontally_stretchable = true - header.style.use_header_filler = false - - header.add{ - type='label', - style='heading_1_label', - caption=caption, - tooltip=tooltip - } - - return right_align and Gui.create_alignment(header,'header-align') or header -end - -return Gui \ No newline at end of file diff --git a/expcore/gui/elements/buttons.lua b/expcore/gui/elements/buttons.lua deleted file mode 100644 index aa06f58b..00000000 --- a/expcore/gui/elements/buttons.lua +++ /dev/null @@ -1,128 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Buttons. --- Gui class define for buttons and sprite buttons --- @section Buttons - ---[[ ->>>> Functions - Button.new_button(name) --- Creates a new button element define - - Button._prototype:on_click(player,element) --- Registers a handler for when the button is clicked - Button._prototype:on_left_click(player,element) --- Registers a handler for when the button is clicked with the left mouse button - Button._prototype:on_right_click(player,element) --- Registers a handler for when the button is clicked with the right mouse button - - Button._prototype:set_sprites(sprite,hovered_sprite,clicked_sprite) --- Adds sprites to a button making it a sprite button - Button._prototype:set_click_filter(filter,...) --- Adds a click / mouse button filter to the button - Button._prototype:set_key_filter(filter,...) --- Adds a control key filter to the button - - Other functions present from expcore.gui.core -]] -local mod_gui = require 'mod-gui' --- @dep mod-gui -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype - -local Button = { - _prototype=Prototype.extend{ - on_raw_click = Prototype.event, - on_click = Prototype.event, - on_left_click = Prototype.event, - on_right_click = Prototype.event, - } -} - ---- Creates a new button element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new button element define -function Button.new_button(name) - - local self = Gui.new_define(Button._prototype,name) - self.draw_data.type = 'button' - self.draw_data.style = mod_gui.button_style - - Gui.on_click(self.name,function(event) - local mouse_button = event.button - local keys = {alt=event.alt,control=event.control,shift=event.shift} - local player,element = event.player,event.element - event.keys = keys - - self:raise_event('on_raw_click',event) - - if self.post_authenticator then - if not self.post_authenticator(event.player,self.name) then return end - end - - if mouse_button == defines.mouse_button_type.left then - self:raise_event('on_left_click',player,element) - elseif mouse_button == defines.mouse_button_type.right and self.events.on_right_click then - self:raise_event('on_right_click',player,element) - end - - if self.mouse_button_filter and not self.mouse_button_filter[mouse_button] then return end - if self.key_button_filter then - for key,state in pairs(self.key_button_filter) do - if state and not keys[key] then return end - end - end - - self:raise_event('on_click',player,element) - end) - - return self -end - ---- Adds sprites to a button making it a sprite button --- @tparam SpritePath sprite the sprite path for the default sprite for the button --- @tparam[opt] SpritePath hovered_sprite the sprite path for the sprite when the player hovers over the button --- @tparam[opt] SpritePath clicked_sprite the sprite path for the sprite when the player clicks the button --- @treturn self returns the button define to allow chaining -function Button._prototype:set_sprites(sprite,hovered_sprite,clicked_sprite) - self.draw_data.type = 'sprite-button' - self.draw_data.sprite = sprite - self.draw_data.hovered_sprite = hovered_sprite - self.draw_data.clicked_sprite = clicked_sprite - return self -end - ---- Adds a click / mouse button filter to the button --- @tparam table filter ?string|table either a of mouse buttons or the first mouse button to filter, with a table true means allowed --- @tparam[opt] table ... when filter is not a you can add the mouse buttons one after each other --- @treturn self returns the button define to allow chaining -function Button._prototype:set_click_filter(filter,...) - if type(filter) == 'string' then - filter = {[filter]=true} - for _,v in pairs({...}) do - filter[v] = true - end - end - - for k,v in pairs(filter) do - if type(v) == 'string' then - filter[k] = defines.mouse_button_type[v] - end - end - - self.mouse_button_filter = filter - return self -end - ---- Adds a control key filter to the button --- @tparam table filter ?string|table either a of control keys or the first control keys to filter, with a table true means allowed --- @tparam[opt] table ... when filter is not a you can add the control keys one after each other --- @treturn self returns the button define to allow chaining -function Button._prototype:set_key_filter(filter,...) - if type(filter) == 'string' then - filter = {[filter]=true} - for _,v in pairs({...}) do - filter[v] = true - end - end - - self.key_button_filter = filter - return self -end - -return Button \ No newline at end of file diff --git a/expcore/gui/elements/checkbox.lua b/expcore/gui/elements/checkbox.lua deleted file mode 100644 index ce9b2a8a..00000000 --- a/expcore/gui/elements/checkbox.lua +++ /dev/null @@ -1,247 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Checkboxs. --- Gui class define for checkbox and radiobuttons --- @section checkboxs - ---[[ ->>>> Using an option set - An option set is a set of radio buttons where only one of them can be active at a time, this means that when one - is clicked all the other ones are set to false, an option set must be defined before hand and will always store - its state but is not limited by how it can categorize the store. - - First you must register the store with a name and a update callback, and an optional function for categorize: - - local example_option_set = - Gui.new_option_set('example-option-set',function(value,category) - game.print('Example options set '..category..' is now: '..tostring(value)) - end,Gui.categorize_by_player) - - Then you must register some radiobutton defines and include them in the option set: - - local example_option_one = - Gui.new_radiobutton() - :set_caption('Option One') - :add_as_option(example_option_set,'One') - - local example_option_two = - Gui.new_radiobutton() - :set_caption('Option Two') - :add_as_option(example_option_set,'Two') - - Note that these radiobuttons can still have on_element_update events but this may result in a double trigger of events as - the option set update is always triggered; also add_store cant be used as the option set acts as the store however get - and set store will still work but will effect the option set rather than the individual radiobuttons. - ->>>> Functions - Checkbox.new_checkbox(name) --- Creates a new checkbox element define - Checkbox._prototype_checkbox:on_element_update(callback) --- Registers a handler for when an element instance updates - Checkbox._prototype_checkbox:on_store_update(callback) --- Registers a handler for when the stored value updates - - Checkbox.new_radiobutton(name) --- Creates a new radiobutton element define - Checkbox._prototype_radiobutton:on_element_update(callback) --- Registers a handler for when an element instance updates - Checkbox._prototype_radiobutton:on_store_update(callback) --- Registers a handler for when the stored value updates - Checkbox._prototype_radiobutton:add_as_option(option_set,option_name) --- Adds this radiobutton to be an option in the given option set (only one can be true at a time) - - Checkbox.new_option_set(name,callback,categorize) --- Registers a new option set that can be linked to radiobutton (only one can be true at a time) - Checkbox.draw_option_set(name,element) --- Draws all radiobuttons that are part of an option set at once (Gui.draw will not work) - - Checkbox.reset_radiobutton(element,exclude,recursive) --- Sets all radiobutton in a element to false (unless excluded) and can act recursively - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Store = require 'expcore.store' --- @dep expcore.store -local Game = require 'utils.game' --- @dep utils.game - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam boolean value the new state of the checkbox -local function store_update(define,element,value) - element.state = value - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_element_update',player,element,value) -end - -local Checkbox = { - option_sets={}, - option_categorize={}, - _prototype_checkbox=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - }, - _prototype_radiobutton=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new checkbox element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new checkbox element define -function Checkbox.new_checkbox(name) - - local self = Gui.new_define(Checkbox._prototype_checkbox,name) - self.draw_data.type = 'checkbox' - self.draw_data.state = false - - self:on_draw(function(player,element) - if self.store then - local state = self:get_store(element,true) - if state then element.state = true end - end - end) - - Gui.on_checked_state_changed(self.name,function(event) - local element = event.element - - if self.option_set then - local value = Checkbox.option_sets[self.option_set][element.name] - self:set_store(element,value) - - elseif self.store then - local value = element.state - self:set_store(element,value) - - else - self:raise_event('on_element_update',event.player,element,element.state) - - end - end) - - return self -end - ---- Creates a new radiobutton element define, has all functions checkbox has --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new button element define -function Checkbox.new_radiobutton(name) - local self = Checkbox.new_checkbox(name) - self.draw_data.type = 'radiobutton' - - local mt = getmetatable(self) - mt.__index = Checkbox._prototype_radiobutton - - return self -end - ---- Adds this radiobutton to be an option in the given option set (only one can be true at a time) --- @tparam string option_set the name of the option set to add this element to --- @tparam string option_name the name of this option that will be used to identify it --- @treturn self the define to allow chaining -function Checkbox._prototype_radiobutton:add_as_option(option_set,option_name) - self.option_set = option_set - self.option_name = option_name or self.name - - Checkbox.option_sets[option_set][self.option_name] = self.name - Checkbox.option_sets[option_set][self.name] = self.option_name - - self:add_store(Checkbox.option_categorize[option_set]) - - return self -end - ---- Gets the stored value of the radiobutton or the option set if present --- @tparam string category[opt] the category to get such as player name or force name --- @tparam boolean internal used to prevent stackover flow --- @treturn any the value that is stored for this define -function Checkbox._prototype_radiobutton:get_store(category,internal) - if not self.store then return end - local location = not internal and self.option_set or self.store - return Store.get(location,category) -end - ---- Sets the stored value of the radiobutton or the option set if present --- @tparam string category[opt] the category to get such as player name or force name --- @tparam boolean value the value to set for this define, must be valid for its type ie for checkbox etc --- @tparam boolean internal used to prevent stackover flow --- @treturn boolean true if the value was set -function Checkbox._prototype_radiobutton:set_store(category,value,internal) - if not self.store then return end - local location = not internal and self.option_set or self.store - return Store.set(location,category,value) -end - ---- Registers a new option set that can be linked to radiobuttons (only one can be true at a time) --- @tparam function callback the update callback when the value of the option set changes --- callback param - value string - the new selected option for this option set --- callback param - category string - the category that updated if categorize was used --- @tparam function categorize the function used to convert an element into a string --- @treturn string the name of this option set to be passed to add_as_option -function Checkbox.new_option_set(callback,categorize) - local name = Store.register(categorize) - - Store.watch(name,function(value,category) - local options = Checkbox.option_sets[name] - for opt_name,define_name in pairs(options) do - if Gui.defines[define_name] then - local define = Gui.get_define(define_name) - local state = opt_name == value - define:set_store(category,state,true) - end - end - callback(value,category) - end) - - Checkbox.option_categorize[name] = categorize - Checkbox.option_sets[name] = {} - - return name -end - ---- Draws all radiobuttons that are part of an option set at once (Gui.draw will not work) --- @tparam string name the name of the option set to draw the radiobuttons of --- @tparam LuaGuiElement element the parent element that the radiobuttons will be drawn to -function Checkbox.draw_option_set(name,element) - if not Checkbox.option_sets[name] then return end - local options = Checkbox.option_sets[name] - - for _,option in pairs(options) do - if Gui.defines[option] then - Gui.defines[option]:draw_to(element) - end - end - -end - ---- Sets all radiobutton in a element to false (unless excluded) and can act recursively --- @tparam LuaGuiElement element the root gui element to start setting radio buttons from --- @tparam[opt] table exclude ?string|table the name of the radiobutton to exclude or a of radiobuttons where true will set the state true --- @tparam[opt=false] ?number|boolean recursive if true will recur as much as possible, if a will recur that number of times --- @treturn boolean true if successful -function Checkbox.reset_radiobuttons(element,exclude,recursive) - if not element or not element.valid then return end - exclude = type(exclude) == 'table' and exclude or exclude ~= nil and {[exclude]=true} or {} - recursive = type(recursive) == 'number' and recursive-1 or recursive - - for _,child in pairs(element.children) do - if child and child.valid and child.type == 'radiobutton' then - local state = exclude[child.name] or false - local define = Gui.defines[child.name] - - if define then - local category = define.categorize and define.categorize(child) or state - define:set_store(category,state) - - else - child.state = state - - end - - elseif child.children and (type(recursive) == 'number' and recursive >= 0 or recursive == true) then - Checkbox.reset_radiobutton(child,exclude,recursive) - - end - end - - return true -end - -return Checkbox \ No newline at end of file diff --git a/expcore/gui/elements/dropdown.lua b/expcore/gui/elements/dropdown.lua deleted file mode 100644 index ae6857c0..00000000 --- a/expcore/gui/elements/dropdown.lua +++ /dev/null @@ -1,184 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Dropdowns. --- Gui class define for dropdowns and list box --- @section dropdowns - ---[[ ->>>> Functions - Dropdown.new_dropdown(name) --- Creates a new dropdown element define - Dropdown.new_list_box(name) --- Creates a new list box element define - - Dropdown._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - Dropdown._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates - - Dropdown._prototype:new_static_options(options,...) --- Adds new static options to the dropdown which will trigger the general callback - Dropdown._prototype:new_dynamic_options(callback) --- Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options) - Dropdown._prototype:add_option_callback(option,callback) --- Adds a case specific callback which will only run when that option is selected (general case still triggered) - - Dropdown.select_value(element,value) --- Selects the option from a dropdown or list box given the value rather than key - Dropdown.get_selected_value(element) --- Returns the currently selected value rather than index - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Game = require 'utils.game' --- @dep utils.game - -local select_value ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam string value the new option for the dropdown -local function store_update(define,element,value) - select_value(element,value) - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_element_update',player,element,value) - - if define.option_callbacks and define.option_callbacks[value] then - define.option_callbacks[value](player,element,value) - end -end - -local Dropdown = { - _prototype=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new dropdown element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new dropdown element define -function Dropdown.new_dropdown(name) - - local self = Gui.new_define(Dropdown._prototype,name) - self.draw_data.type = 'drop-down' - - self:on_draw(function(player,element) - if self.dynamic_options then - local dynamic_options = self.dynamic_options(player,element) - local items = element.items - for _,v in pairs(dynamic_options) do - table.insert(items,v) - end - element.items = items - end - - if self.store then - local value = self:get_store(element) - if value then Dropdown.select_value(element,value) end - end - end) - - Gui.on_selection_state_changed(self.name,function(event) - local element = event.element - local value = Dropdown.get_selected_value(element) - - if self.store then - self:set_store(element,value) - - else - local player = event.player - local option_callbacks = self.option_callbacks - self:raise_event('on_element_update',player,element,value) - if option_callbacks and option_callbacks[value] then - option_callbacks[value](player,element,value) - end - - end - - end) - - return self -end - ---- Creates a new list box element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new list box element define -function Dropdown.new_list_box(name) - local self = Dropdown.new_dropdown(name) - self.draw_data.type = 'list-box' - - return self -end - ---- Adds new static options to the dropdown which will trigger the general callback --- @tparam table options ?string|table either a of option strings or the first option string, with a table values are the options --- @tparam[opt] table ... when options is not a you can add the options one after each other --- @tparam self the define to allow chaining -function Dropdown._prototype:new_static_options(options,...) - if type(options) == 'string' then - options = {options} - for _,v in pairs({...}) do - table.insert(options,v) - end - end - - self.options = options - self.draw_data.items = options - return self -end -Dropdown._prototype.add_options = Dropdown._prototype.new_static_options - ---- Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options) --- @tparam function callback the function that will run to get the options for the dropdown --- callback param - player LuaPlayer - the player that the element is being drawn to --- callback param - element LuaGuiElement - the element that is being drawn --- callback return - table - the values of this table will be appended to the static options of the dropdown --- @treturn self the define to allow chaining -function Dropdown._prototype:new_dynamic_options(callback) - if type(callback) ~= 'function' then - return error('Dynamic options callback must be a function',2) - end - self.dynamic_options = callback - return self -end -Dropdown._prototype.add_dynamic = Dropdown._prototype.new_dynamic_options - ---- Adds a case specific callback which will only run when that option is selected (general case still triggered) --- @tparam string option the name of the option to trigger the callback on; if not already added then will be added as an option --- @tparam function callback the function that will be called when that option is selected --- callback param - player LuaPlayer - the player who owns the gui element --- callback param - element LuaGuiElement - the element which is being effected --- callback param - value string - the new option that has been selected --- @treturn self the define to allow chaining -function Dropdown._prototype:add_option_callback(option,callback) - if not self.option_callbacks then self.option_callbacks = {} end - if not self.options then self.options = {} end - - self.option_callbacks[option] = callback - if not table.contains(self.options,option) then - table.insert(self.options,option) - end - - return self -end - ---- Selects the option from a dropdown or list box given the value rather than key --- @tparam LuaGuiElement element the element that contains the option --- @tparam string value the option to select from the dropdown --- @treturn number the key where the value was -function Dropdown.select_value(element,value) - for k,item in pairs(element.items) do - if item == value then - element.selected_index = k - return k - end - end -end -select_value = Dropdown.select_value - ---- Returns the currently selected value rather than index --- @tparam LuaGuiElement element the gui element that you want to get the value of --- @treturn string the value that is currently selected -function Dropdown.get_selected_value(element) - local index = element.selected_index - return element.items[index] -end - -return Dropdown \ No newline at end of file diff --git a/expcore/gui/elements/elem-button.lua b/expcore/gui/elements/elem-button.lua deleted file mode 100644 index 8b2b2b3c..00000000 --- a/expcore/gui/elements/elem-button.lua +++ /dev/null @@ -1,96 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Elem Buttons. --- Gui class defines for elem buttons --- @section elem-buttons - ---[[ ->>>> Functions - ElemButton.new_elem_button(name) --- Creates a new elem button element define - - ElemButton._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - ElemButton._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates - - ElemButton._prototype:set_type(type) --- Sets the type of the elem button, the type is required so this must be called at least once - ElemButton._prototype:set_default(value) --- Sets the default value for the elem button, this may be a function or a string - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Game = require 'utils.game' --- @dep utils.game - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam string value the new value for the elem button -local function store_update(define,element,value) - element.elem_value = value - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_element_update',player,element,value) -end - -local ElemButton = { - _prototype=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new elem button element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new elem button element define -function ElemButton.new_elem_button(name) - - local self = Gui.new_define(ElemButton._prototype,name) - self.draw_data.type = 'choose-elem-button' - - self:on_draw(function(player,element) - if type(self.default) == 'function' then - element.elem_value = self.default(player,element) - end - - if self.store then - local value = self:get_store(element) - if value then element.elem_value = value end - end - end) - - Gui.on_elem_changed(self.name,function(event) - local element = event.element - local value = element.elem_value - - if self.store then - self:set_store(element,value) - - else - self:raise_event('on_element_update',event.player,element,value) - - end - - end) - - return self -end - ---- Sets the type of the elem button, the type is required so this must be called at least once --- @tparam string type the type that this elem button is see factorio api --- @treturn the element define to allow for chaining -ElemButton._prototype.set_type = Prototype.setter('string','draw_data','elem_type') - ---- Sets the default value for the elem button, this may be a function or a string --- @tparam ?string|function value string a will be a static default and a function will be called when drawn to get the default --- @treturn the element define to allow for chaining -function ElemButton._prototype:set_default(value) - self.default = value - if type(value) ~= 'function' then - self.draw_data[self.draw_data.elem_type] = value - end - return self -end - -return ElemButton \ No newline at end of file diff --git a/expcore/gui/elements/progress-bar.lua b/expcore/gui/elements/progress-bar.lua deleted file mode 100644 index 0e096d42..00000000 --- a/expcore/gui/elements/progress-bar.lua +++ /dev/null @@ -1,387 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Progress Bars. --- Gui element define for progress bars --- @section progress-bars - ---[[ ->>>> Functions - ProgressBar.set_maximum(element,amount,count_down) --- Sets the maximum value that represents the end value of the progress bar - ProgressBar.increment(element,amount) --- Increases the value of the progressbar, if a define is given all of its instances have incremented - ProgressBar.decrement(element,amount) --- Decreases the value of the progressbar, if a define is given all of its instances have decremented - - ProgressBar.new_progressbar(name) --- Creates a new progressbar element define - ProgressBar._prototype:set_maximum(amount,count_down) --- Sets the maximum value that represents the end value of the progress bar - ProgressBar._prototype:use_count_down(state) --- Will set the progress bar to start at 1 and trigger when it hits 0 - ProgressBar._prototype:increment(amount,category) --- Increases the value of the progressbar - ProgressBar._prototype:increment_filtered(amount,filter) --- Increases the value of the progressbar, if the filter condition is met, does not work with store - ProgressBar._prototype:decrement(amount,category) --- Decreases the value of the progressbar - ProgressBar._prototype:decrement_filtered(amount,filter) --- Decreases the value of the progressbar, if the filter condition is met, does not work with store - ProgressBar._prototype:add_element(element,maximum) --- Adds an element into the list of instances that will are waiting to complete, does not work with store - ProgressBar._prototype:reset_element(element) --- Resets an element, or its store, to be back at the start, either 1 or 0 - - ProgressBar._prototype:on_complete(callback) --- Triggers when a progress bar element completes (hits 0 or 1) - ProgressBar._prototype:on_complete(callback) --- Triggers when a store value completes (hits 0 or 1) - ProgressBar._prototype:event_counter(filter) --- Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented - ProgressBar._prototype:event_countdown(filter) --- Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Global = require 'utils.global' --- @dep utils.global -local Game = require 'utils.game' --- @dep utils.game - ---- Event call for when the value is outside the range 0-1 --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event -local function event_call(define,element) - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_complete',player,element,function() - define:add_element(element) - define:reset_element(element) - end) -end - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam number value the new value for the progress bar -local function store_update(define,element,value) - if value then - element.value = value - if define.count_down and value <= 0 - or not define.count_down and value >= 1 then - event_call(define,element) - end - end -end - -local ProgressBar = { - unregistered={}, -- elements with no callbacks - independent={}, -- elements with a link to a define - _prototype=Prototype.extend{ - on_complete = Prototype.event, - on_store_complete = Prototype.event, - add_store = Prototype.store(store_update) - } -} - -Global.register({ - unregistered = ProgressBar.unregistered, - independent = ProgressBar.independent -},function(tbl) - ProgressBar.unregistered = tbl.unregistered - ProgressBar.independent = tbl.independent -end) - ---- Gets the define data, cant use Gui.get_define as it would error --- @tparam ?table|string define the define to get --- @treturn table the define or nil -local function get_define(define) - if type(define) == 'table' then - if define.name and Gui.defines[define.name] then - return Gui.defines[define.name] - end - end - - return Gui.defines[define] -end - ---- Gets the element data, used when there is no define --- @tparam LuaGuiElement element the element to get the data of --- @treturn table the element data similar to define -local function get_element(element) - if not element.valid then return end - local name = element.player_index..':'..element.index - - if ProgressBar.unregistered[name] then - return ProgressBar.unregistered[name] - end -end - ---- Sets the maximum value that represents the end value of the progress bar --- @tparam ?LuaGuiElement|string element either a gui element or a registered define --- @tparam number amount the amount to have set as the maximum -function ProgressBar.set_maximum(element,amount) - amount = amount > 0 and amount or error('amount must be greater than 0') - - local define = get_define(element) - if define then - define:set_default_maximum(amount) - - else - local element_data = get_element(element) - - if element_data then - element_data.maximum = amount - - else - local name = element.player_index..':'..element.index - ProgressBar.unregistered[name] = { - element=element, - maximum=amount or 1 - } - - end - - end -end - ---- Increases the value of the progressbar, if a define is given all of its instances have incremented --- @tparam ?LuaGuiElement|string element either a gui element or a registered define --- @tparam[opt=1] number amount the amount to increase the progressbar by -function ProgressBar.increment(element,amount) - amount = type(amount) == 'number' and amount or 1 - - local define = get_define(element) - if define then - define:increment(amount) - - else - local element_data = get_element(element) - - if element_data then - local real_amount = amount/element_data.maximum - element.value = element.value + real_amount - - if element.value >= 1 then - local name = element.player_index..':'..element.index - ProgressBar.unregistered[name] = nil - return true - end - end - - end -end - ---- Decreases the value of the progressbar, if a define is given all of its instances have decremented --- @tparam ?LuaGuiElement|string element either a gui element or a registered define --- @tparam[opt=1] number amount the amount to decrease the progressbar by -function ProgressBar.decrement(element,amount) - amount = type(amount) == 'number' and amount or 1 - - local define = get_define(element) - if define then - define:decrement(amount) - - else - local element_data = get_element(element) - - if element_data then - local real_amount = amount/element_data.maximum - element.value = element.value - real_amount - - if element.value <= 0 then - local name = element.player_index..':'..element.index - ProgressBar.unregistered[name] = nil - return true - end - end - - end -end - ---- Creates a new progressbar element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new progressbar element define -function ProgressBar.new_progressbar(name) - - local self = Gui.new_define(ProgressBar._prototype,name) - self.draw_data.type = 'progressbar' - - self:on_draw(function(player,element,maximum) - if self.store then - local value = self:get_store(element) - if not value then - value = self.count_down and 1 or 0 - self:set_store(element,value) - end - element.value = value - - else - if self.count_down then - element.value = 1 - end - - if not ProgressBar.independent[self.name] then - ProgressBar.independent[self.name] = {} - end - - table.insert(ProgressBar.independent[self.name],{ - element = element, - maximum = maximum - }) - - end - - end) - - return self -end - ---- Sets the maximum value that represents the end value of the progress bar --- @tparam number amount the amount to have set as the maximum --- @treturn table the define to allow chaining -function ProgressBar._prototype:set_default_maximum(amount) - amount = amount > 0 and amount or error('amount must be greater than 0') - self.default_maximum = amount - return self -end - ---- Will set the progress bar to start at 1 and trigger when it hits 0 --- @tparam[opt=true] boolean state when true the bar will start filled, to be used with decrease --- @treturn table the define to allow chaining -function ProgressBar._prototype:use_count_down(state) - if state == false then - self.count_down = false - else - self.count_down = true - end - return self -end - ---- Main logic for changing the value of a progress bar, this only applies when its a registered define --- @tparam table self the define that is being changed --- @tparam number amount the amount which it is being changed by, may be negative --- @tparam[opt] string category the category to use with store --- @tparam[opt] function filter when given the filter must return true for the value of the element to be changed -local function change_value_prototype(self,amount,category,filter) - - local function reset_store() - local value = self.count_down and 1 or 0 - self:set_store(category,value) - end - - if self.store then - local value = self:get_store(category) or self.count_down and 1 or 0 - local maximum = self.default_maximum or 1 - local new_value = value + (amount/maximum) - - self:set_store(category,new_value) - - if self.count_down and new_value <= 0 - or not self.count_down and new_value >= 1 then - self:clear_store(category) - self:raise_event('on_store_complete',category,reset_store) - return - end - - return - end - - if ProgressBar.independent[self.name] then - for key,element_data in pairs(ProgressBar.independent[self.name]) do - local element = element_data.element - if not element or not element.valid then - ProgressBar.independent[self.name][key] = nil - - else - if not filter or filter(element) then - local maximum = element_data.maximum or self.default_maximum or 1 - element.value = element.value + (amount/maximum) - - if self.count_down and element.value <= 0 - or not self.count_down and element.value >= 1 then - ProgressBar.independent[self.name][key] = nil - event_call(self,element) - end - end - - end - end - end - -end - ---- Increases the value of the progressbar --- @tparam[opt=1] number amount the amount to increase the progressbar by --- @tparam[opt] string category the category that is used with a store -function ProgressBar._prototype:increment(amount,category) - amount = type(amount) == 'number' and amount or 1 - change_value_prototype(self,amount,category) -end - ---- Increases the value of the progressbar, if the filter condition is met, does not work with store --- @tparam[opt=1] number amount the amount to increase the progressbar by --- @tparam function filter the filter to be used -function ProgressBar._prototype:increment_filtered(amount,filter) - amount = type(amount) == 'number' and amount or 1 - change_value_prototype(self,amount,nil,filter) -end - ---- Decreases the value of the progressbar --- @tparam[opt=1] number amount the amount to decrease the progressbar by --- @tparam[opt] string category the category that is used with a store -function ProgressBar._prototype:decrement(amount,category) - amount = type(amount) == 'number' and amount or 1 - change_value_prototype(self,-amount,category) -end - ---- Decreases the value of the progressbar, if the filter condition is met, does not work with store --- @tparam[opt=1] number amount the amount to decrease the progressbar by --- @tparam function filter the filter to be used -function ProgressBar._prototype:decrement_filtered(amount,filter) - amount = type(amount) == 'number' and amount or 1 - change_value_prototype(self,-amount,nil,filter) -end - ---- Adds an element into the list of instances that will are waiting to complete, does not work with store --- note use store if you want persistent data, this only stores the elements not the values which they have --- @tparam LuaGuiElement element the element that you want to add into the waiting to complete list --- @tparam[opt] number maximum the maximum for this element if not given the default for this define is used -function ProgressBar._prototype:add_element(element,maximum) - if self.store then return end - if not ProgressBar.independent[self.name] then - ProgressBar.independent[self.name] = {} - end - table.insert(ProgressBar.independent[self.name],{ - element = element, - maximum = maximum - }) -end - ---- Resets an element, or its store, to be back at the start, either 1 or 0 --- @tparam LuaGuiElement element the element that you want to reset the progress of -function ProgressBar._prototype:reset_element(element) - if not element or not element.valid then return end - local value = self.count_down and 1 or 0 - if self.store then - self:set_store(element,value) - else - element.value = value - end -end - ---- Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented --- @tparam[opt] function filter when given will use filtered increment --- @treturn function the event handler -function ProgressBar._prototype:event_counter(filter) - if type(filter) == 'function' then - return function() - self:increment_filtered(1,filter) - end - else - return function() - self:increment() - end - end -end - ---- Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented --- @tparam[opt] function filter when given will use filtered decrement --- @treturn function the event handler -function ProgressBar._prototype:event_countdown(filter) - if type(filter) == 'function' then - return function() - self:decrement_filtered(1,filter) - end - else - return function() - self:decrement() - end - end -end - -return ProgressBar \ No newline at end of file diff --git a/expcore/gui/elements/slider.lua b/expcore/gui/elements/slider.lua deleted file mode 100644 index e8099b06..00000000 --- a/expcore/gui/elements/slider.lua +++ /dev/null @@ -1,173 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Sliders. --- Gui class define for sliders --- @section sliders - ---[[ ->>>> Functions - Slider.new_slider(name) --- Creates a new slider element define - - Slider._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates - Slider._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates - - Slider._prototype:set_range(min,max) --- Sets the range of a slider, if not used will use default values for a slider - Slider._prototype:draw_label(element) --- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player - Slider._prototype:enable_auto_draw_label(state) --- Enables auto draw of the label, the label will share the same parent element as the slider - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Instances = require 'expcore.gui.instances' --- @dep expcore.gui.instances -local Game = require 'utils.game' --- @dep utils.game - ---- Event call for on_value_changed and store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam number value the new value for the slider -local function event_call(define,element,value) - local player = Game.get_player_by_index(element.player_index) - - local min,max = element.get_slider_minimum(),element.get_slider_maximum() - local delta = max-min - local percent = delta == 0 and 0 or (value-min)/delta - - define:raise_event('on_element_update',player,element,value,percent) - - local category = player.name - if define.categorize then - category = define.categorize(element) - end - - Instances.unregistered_get_elements(define.name..'-label',category,function(label) - label.caption = tostring(math.round(value,2)) - end) -end - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam number value the new value for the slider -local function store_update(define,element,value) - element.slider_value = value - event_call(define,element,value) -end - -local Slider = { - _prototype=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new slider element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new slider element define -function Slider.new_slider(name) - - local self = Gui.new_define(Slider._prototype,name) - self.draw_data.type = 'slider' - - self:on_draw(function(player,element) - local min,max = element.get_slider_minimum(),element.get_slider_maximum() - - if type(self.min) == 'function' then - min = self.min(player,element) - end - - if type(self.max) == 'function' then - max = self.max(player,element) - end - - element.set_slider_minimum_maximum(min,max) - - if self.store then - local value = self:get_store(element) - if value then element.slider_value = value end - end - - if self.auto_label then - self:draw_label(element.parent) - end - end) - - Gui.on_value_changed(self.name,function(event) - local element = event.element - local value = element.slider_value - - if self.store then - self:set_store(element,value) - - else - event_call(self,element,value) - - end - - end) - - return self -end - ---- Sets the range of a slider, if not used will use default values for a slider --- @tparam[opt] number min the minimum value that the slider can take --- @tparam[opt] number max the maximum value that the slider can take --- @treturn self the define to allow chaining -function Slider._prototype:set_range(min,max) - self.min = min - self.max = max - - if type(min) == 'number' then - self.draw_data.minimum_value = min - end - - if type(max) == 'number' then - self.draw_data.maximum_value = max - end - - return self -end - ---- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player --- @tparam LuaGuiElement element the parent element that the label will be drawn to --- @treturn LuaGuiElement the new label element so that styles can be applied -function Slider._prototype:draw_label(element) - local name = self.name..'-label' - if element[name] then return end - - local value = 0 - if self.store then - value = self:get_store(element) or 0 - end - - local new_element = element.add{ - name=name, - type='label', - caption=tostring(math.round(value,2)) - } - - local categorise = self.categorise or Gui.categorize_by_player - local category = categorise(new_element) - - Instances.unregistered_add_element(name,category,new_element) - - return new_element -end - ---- Enables auto draw of the label, the label will share the same parent element as the slider --- @tparam[opt=true] boolean state when false will disable the auto draw of the label --- @treturn self the define to allow chaining -function Slider._prototype:enable_auto_draw_label(state) - if state == false then - self.auto_label = false - else - self.auto_label = true - end - return self -end - -return Slider \ No newline at end of file diff --git a/expcore/gui/elements/text.lua b/expcore/gui/elements/text.lua deleted file mode 100644 index 56709ede..00000000 --- a/expcore/gui/elements/text.lua +++ /dev/null @@ -1,145 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Text. --- Gui class define for text fields and text boxes --- @section text - ---[[ ->>>> Functions - Text.new_text_field(name) --- Creates a new text field element define - Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates - Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates - - Text.new_text_box(name) --- Creates a new text box element define - Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates - Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates - Text._prototype_box:set_selectable(state) --- Sets the text box to be selectable - Text._prototype_box:set_word_wrap(state) --- Sets the text box to have word wrap - Text._prototype_box:set_read_only(state) --- Sets the text box to be read only - - Other functions present from expcore.gui.core -]] -local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core -local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype -local Game = require 'utils.game' --- @dep utils.game - ---- Store call for store update --- @tparam table define the define that this is acting on --- @tparam LuaGuiElement element the element that triggered the event --- @tparam string value the new text for the text field -local function store_update(define,element,value) - element.text = value - local player = Game.get_player_by_index(element.player_index) - define:raise_event('on_element_update',player,element,value) -end - -local Text = { - _prototype_field=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - }, - _prototype_box=Prototype.extend{ - on_element_update = Prototype.event, - on_store_update = Prototype.event, - add_store = Prototype.store(store_update) - } -} - ---- Creates a new text field element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new text field element define -function Text.new_text_field(name) - - local self = Gui.new_define(Text._prototype_field,name) - self.draw_data.type = 'textfield' - - self:on_draw(function(player,element) - if self.selectable then - element.selectable = true - end - - if self.word_wrap then - element.word_wrap = true - end - - if self.read_only then - element.read_only = true - end - - if self.store then - local value = self:get_store(element) - if value then element.text = value end - end - end) - - Gui.on_text_changed(self.name,function(event) - local element = event.element - local value = element.text - - if self.store then - self:set_store(element,value) - - else - self:raise_event('on_element_update',event.player,element,value) - - end - - end) - - return self -end - ---- Creates a new text box element define --- @tparam[opt] string name the optional debug name that can be added --- @treturn table the new text box element define -function Text.new_text_box(name) - local self = Text.new_text_field(name) - self.draw_data.type = 'text-box' - - local mt = getmetatable(self) - mt.__index = Text._prototype_box - - return self -end - ---- Sets the text box to be selectable --- @tparam[opt=true] boolean state when false will set the state to false --- @treturn self table the define to allow for chaining -function Text._prototype_box:set_selectable(state) - if state == false then - self.selectable = false - else - self.selectable = true - end - return self -end - ---- Sets the text box to have word wrap --- @tparam[opt=true] boolean state when false will set the state to false --- @treturn self table the define to allow for chaining -function Text._prototype_box:set_word_wrap(state) - if state == false then - self.word_wrap = false - else - self.word_wrap = true - end - return self -end - ---- Sets the text box to be read only --- @tparam[opt=true] boolean state when false will set the state to false --- @treturn self table the define to allow for chaining -function Text._prototype_box:set_read_only(state) - if state == false then - self.read_only = false - else - self.read_only = true - end - return self -end - -return Text \ No newline at end of file diff --git a/expcore/gui/instances.lua b/expcore/gui/instances.lua deleted file mode 100644 index 2db7273e..00000000 --- a/expcore/gui/instances.lua +++ /dev/null @@ -1,235 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Instances. --- This file is a breakout from core which forcues on instance management of defines --- @section instances - ---[[ ->>>> Using registered instance groups - The main use of this module is to register a group of elements referred here as "instances of an element define" in which - is meant that you define the name of a group of drawn elements that are really just multiple versions of a single element. - For example this might be that you have one label in multiple places (either for one player or many) and you want to update - the caption of all of them at once; this is where this module comes it. - - First you must register the way that the instances are stored and under what name, using Instances.register you will give the - name of the collective group of instances followed by an optional serializer function which allows variants to be stored under one - name (like one for each force or player) - - -- serializer works in the same way as store serializer - -- so the function will world here but no value is stored only gui elements - Instances.register('score',Gui.categorize_by_force) - - Then when you draw the new element to a gui you will want to add the element to the group: - - Instances.add_element('score',new_element) - - Then when you want to get the instances you have two options; Instances.get_elements or Instances.apply_to_elements when you want loop - over the elements it is more efficient to use apply_to_elements: - - Instances.get_elements('score','player') -- returns all elements that were added with the 'player' category - Instances.apply_to_elements('score','player',function(element) -- runs the function on every valid element - element.caption = 0 - end) - - Note that if you don't give a serializer function then you don't need to give a category when getting the elements. - ->>>> Using unregistered instance groups - When using a registered group and the functions that go with them it is much simpler to use and more importantly includes error checking - for valid instance group names; the down side is that the group must be registered which can only be done during start-up and not during runtime. - To counter this there are two functions similar to those above in order to add and get instances but may lead to errors not being noticed due to - the error internal error checking being skipped to allow it to work. - - The main difference between the two groups of functions is that the category must always be present even if is nil; example below shows how a - instance group would work when registered vs unregistered: - - -- Registered with category - Instances.register('score',Gui.categorize_by_force) -- force_store will return the force name of an element - Instances.add_element('score',new_element) -- the new element is added to the category based on in force - Instances.apply_to_elements('score','player',function(element) - element.caption = '0' - end) -- gets all instances from the player force and sets the caption to 0 - - -- Unregistered with category - Instances.unregistered_add_element('score','player',new_element) -- adds the new element to the player category - Instances.unregistered_apply_to_elements('score','player',function(element) - element.caption = '0' - end) -- gets all instances from the player force and sets the caption to 0 - - -- Registered without category; note that category can just be ignored - Instances.register('score') -- all instances will be under one group with no categories - Instances.add_element('score',new_element) -- adds the new element to the instance list - Instances.apply_to_elements('score',function(element) - element.caption = '0' - end) -- gets all instances and sets the element caption to 0 - - -- Unregistered without category; note that category must be given as nil - Instances.unregistered_add_element('score',nil,new_element) -- adds the new element to a single group with no categories - Instances.unregistered_apply_to_elements('score',nil,function(element) - element.caption = '0' - end) -- gets all instances and sets the element caption to 0 - ->>>> Functions - Instances.has_categories(name) --- Returns if a instance group has a serializer function; must be registered - Instances.is_registered(name) --- Returns if the given name is a registered instance group - Instances.register(name,serializer) --- Registers the name of an instance group to allow for storing element instances - - Instances.add_element(name,element) --- Adds an element to the instance group under the correct category; must be registered - Instances.get_elements_raw(name,category) --- Gets all element instances without first removing any invalid ones; used internally and must be registered - Instances.get_valid_elements(name,category,callback) --- Gets all valid element instances and has the option of running a callback on those that are valid - - Instances.unregistered_add_element(name,category,element) --- A version of add_element that does not require the group to be registered - Instances.unregistered_get_elements(name,category,callback) --- A version of get_elements that does not require the group to be registered -]] -local Global = require 'utils.global' --- @dep utils.global - -local Instances = { - serializer={}, - data={} -} -Global.register(Instances.data,function(tbl) - Instances.data = tbl -end) - ---- Returns if a instance group has a serializer function; must be registered --- @tparam string name the name of the instance group --- @treturn boolean true if there is a serializer function -function Instances.has_categories(name) - return type(Instances.serializer[name]) == 'function' -end - ---- Returns if the given name is a registered instance group --- @tparam string name the name of the instance group you are testing --- @treturn boolean true if the name is registered -function Instances.is_registered(name) - return Instances.serializer[name] ~= nil -end - ---- Registers the name of an instance group to allow for storing element instances --- @tparam string name the name of the instance group; must to unique --- @tparam[opt] function serializer function used to turn the element into a string --- serializer param - element LuaGuiElement - the gui element to be turned into a string --- serializer return - string - the category that the element will be added to like the player's name or force's name --- @treturn string the name that was added so it can be used as a variable -function Instances.register(name,serializer) - if _LIFECYCLE ~= _STAGE.control then - return error('Can only be called during the control stage', 2) - end - - if Instances.serializer[name] then - return error('Instances for '..name..' already exist.',2) - end - - serializer = type(serializer) == 'function' and serializer or true - - Instances.data[name] = {} - Instances.serializer[name] = serializer - - return name -end - ---- Adds an element to the instance group under the correct category; must be registered --- @tparam string name the name of the instance group to add the element to --- @tparam LuaGuiElement element the element to add the the instance group -function Instances.add_element(name,element) - if not Instances.serializer[name] then - return error('Invalid name for instance group: '..name,2) - end - - if Instances.has_categories(name) then - local category = Instances.serializer[name](element) - if not Instances.data[name][category] then Instances.data[name][category] = {} end - table.insert(Instances.data[name][category],element) - else - table.insert(Instances.data[name],element) - end -end - ---- Gets all element instances without first removing any invalid ones; used internally and must be registered --- @tparam string name the name of the instance group to get the instances of --- @tparam[opt] string category the category to get the instance from, not needed when no serializer function --- @treturn table the table of element instances of which some may be invalid -function Instances.get_elements_raw(name,category) - if not Instances.serializer[name] then - return error('Invalid name for instance group: '..name,2) - end - - if Instances.has_categories(name) then - return Instances.data[name][category] or {} - else - return Instances.data[name] - end -end - ---- Gets all valid element instances and has the option of running a callback on those that are valid --- @tparam string name the name of the instance group to get the instances of --- @tparam[opt] string category the category to get the instances of, not needed when no serializer function --- @tparam[opt] function callback when given the callback will be ran on all valid elements --- callback param - element LuaGuiElement - the current valid element --- @treturn table the table of element instances with all invalid ones removed -function Instances.get_valid_elements(name,category,callback) - if not Instances.serializer[name] then - return error('Invalid name for instance group: '..name,2) - end - - category = category or callback - local elements = Instances.get_elements_raw(name,category) - local serializer = Instances.has_categories(name) - - for key,element in pairs(elements) do - if not element or not element.valid then - elements[key] = nil - else - if serializer and callback then callback(element) - elseif category then category(element) end - end - end - - return elements -end -Instances.get_elements = Instances.get_valid_elements -Instances.apply_to_elements = Instances.get_valid_elements - ---- A version of add_element that does not require the group to be registered --- @tparam string name the name of the instance group to add the element to --- @tparam ?string|nil category the category to add the element to, can be nil but must still be given --- @tparam LuaGuiElement element the element to add to the instance group -function Instances.unregistered_add_element(name,category,element) - if not Instances.data[name] then Instances.data[name] = {} end - if category then - if not Instances.data[name][category] then Instances.data[name][category] = {} end - table.insert(Instances.data[name][category],element) - else - table.insert(Instances.data[name],element) - end -end - ---- A version of get_elements that does not require the group to be registered --- @tparam string name the name of the instance group to get the instances of --- @tparam ?string|nil category the category to get the instances of, can be nil but must still be given --- @tparam[opt] function callback when given will be called on all valid instances --- callback param - element LuaGuiElement - the current valid element --- @treturn table the table of element instances with all invalid ones removed -function Instances.unregistered_get_elements(name,category,callback) - local elements = Instances.data[name] - if elements and category then - elements = elements[category] - end - - if not elements then return {} end - - for key,element in pairs(elements) do - if not element or not element.valid then - elements[key] = nil - else - if callback then callback(element) end - end - end - - return elements -end -Instances.unregistered_apply_to_elements = Instances.runtime_get_elements - -return Instances \ No newline at end of file diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua deleted file mode 100644 index 790375aa..00000000 --- a/expcore/gui/prototype.lua +++ /dev/null @@ -1,300 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias Prototype -]] - ---- Prototype. --- Used to create new gui prototypes see elements and concepts --- @section prototype - ---[[ - >>>> Functions - Constructor.event(event_name) --- Creates a new function to add functions to an event handler - Constructor.extend(new_prototype) --- Extents a prototype with the base functions of all gui prototypes, no metatables - Constructor.store(sync,callback) --- Creates a new function which adds a store to a gui define - Constructor.setter(value_type,key,second_key) --- Creates a setter function that checks the type when a value is set - - Prototype:uid() --- Gets the uid for the element define - Prototype:debug_name(value) --- Sets a debug alias for the define - Prototype:set_caption(value) --- Sets the caption for the element define - Prototype:set_tooltip(value) --- Sets the tooltip for the element define - Prototype:set_style(style,callback) --- Sets the style for the element define - Prototype:set_embedded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function - - Prototype:set_pre_authenticator --- Sets an authenticator that blocks the draw function if check fails - Prototype:set_post_authenticator --- Sets an authenticator that disables the element if check fails - - Prototype:raise_event(event_name,...) --- Raises a custom event for this define, any number of params can be given - Prototype:draw_to(element,...) --- The main function for defines, when called will draw an instance of this define to the given element - - Prototype:get_store(category) --- Gets the value in this elements store, category needed if serializer function used - Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if serializer function used - Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if serializer function used -]] -local Game = require 'utils.game' --- @dep utils.game -local Store = require 'expcore.store' --- @dep expcore.store -local Instances = require 'expcore.gui.instances' --- @dep expcore.gui.instances - -local Constructor = {} -local Prototype = {} - ---- Creates a new function to add functions to an event handler --- @tparam string event_name the name of the event that callbacks will be added to --- @treturn function the function used to register handlers -function Constructor.event(event_name) - --- Adds a callback as a handler for an event - -- @tparam table self the gui define being acted on - -- @tparam function callback the function that will be added as a handler for the event - -- @treturn table self returned to allowing chaining of functions - return function(self,callback) - if type(callback) ~= 'function' then - return error('Event callback for '..event_name..' must be a function',2) - end - - local handlers = self.events[event_name] - if not handlers then - handlers = {} - self.events[event_name] = handlers - end - - handlers[#handlers+1] = callback - return self - end -end - ---- Extents a prototype with the base functions of all gui prototypes, no metatables --- @tparam table new_prototype the prototype that you want to add the functions to --- @treturn table the same prototype but with the new functions added -function Constructor.extend(new_prototype) - for key,value in pairs(Prototype) do - if type(value) == 'table' then - new_prototype[key] = table.deepcopy(value) - else - new_prototype[key] = value - end - end - for key,value in pairs(new_prototype) do - if value == Constructor.event then - new_prototype[key] = Constructor.event(key) - end - end - return new_prototype -end - ---- Creates a new function which adds a store to a gui define --- @tparam function callback the function called when needing to update the value of an element --- @treturn function the function that will add a store for this define -function Constructor.store(callback) - --- Adds a store for the define that is shared between all instances of the define in the same category, serializer is a function that returns a string - -- @tparam self table the gui define being acted on - -- @tparam[opt] function serializer function used to determine the category of a LuaGuiElement, when omitted all share one single category - -- serializer param - LuaGuiElement element - the element that needs to be converted - -- serializer return - string - a deterministic string that references to a category such as player name or force name - -- @treturn self the element define to allow chaining - return function(self,serializer) - if self.store then return end - serializer = serializer or function() return '' end - - self.store = Store.register(serializer) - - Instances.register(self.name,serializer) - - Store.watch(self.store,function(value,category) - self:raise_event('on_store_update',value,category) - - if Instances.is_registered(self.name) then - Instances.apply_to_elements(self.name,category,function(element) - callback(self,element,value) - end) - end - end) - - return self - end -end - ---- Creates a setter function that checks the type when a value is set --- @tparam string value_type the type that the value should be when it is set --- @tparam string key the key of the define that will be set --- @tparam[opt] string second_key allows for setting of a key in a sub table --- @treturn function the function that will check the type and set the value -function Constructor.setter(value_type,key,second_key) - local display_message = 'Gui define '..key..' must be of type '..value_type - if second_key then - display_message = 'Gui define '..second_key..' must be of type '..value_type - end - - local locale = false - if value_type == 'locale-string' then - locale = true - value_type = 'table' - end - - return function(self,value) - local v_type = type(value) - if v_type ~= value_type and (not locale or v_type ~= 'string') then - error(display_message,2) - end - - if second_key then - self[key][second_key] = value - else - self[key] = value - end - - return self - end -end - ---- Gets the uid for the element define --- @treturn string the uid of this element define -function Prototype:uid() - return self.name -end - ---- Sets a debug alias for the define --- @tparam string name the debug name for the element define that can be used to get this element define --- @treturn self the element define to allow chaining -Prototype.debug_name = Constructor.setter('string','debug_name') - ---- Sets the caption for the element define --- @tparam string caption the caption that will be drawn with the element --- @treturn self the element define to allow chaining -Prototype.set_caption = Constructor.setter('locale-string','draw_data','caption') - ---- Sets the tooltip for the element define --- @tparam string tooltip the tooltip that will be displayed for this element when drawn --- @treturn self the element define to allow chaining -Prototype.set_tooltip = Constructor.setter('locale-string','draw_data','tooltip') - ---- Sets an authenticator that blocks the draw function if check fails --- @tparam function callback the function that will be ran to test if the element should be drawn or not --- callback param - LuaPlayer player - the player that the element is being drawn to --- callback param - string define_name - the name of the define that is being drawn --- callback return - boolean - false will stop the element from being drawn --- @treturn self the element define to allow chaining -Prototype.set_pre_authenticator = Constructor.setter('function','pre_authenticator') - ---- Sets an authenticator that disables the element if check fails --- @tparam function callback the function that will be ran to test if the element should be enabled or not --- callback param - LuaPlayer player - the player that the element is being drawn to --- callback param - string define_name - the name of the define that is being drawn --- callback return - boolean - false will disable the element --- @treturn self the element define to allow chaining -Prototype.set_post_authenticator = Constructor.setter('function','post_authenticator') - ---- Registers a callback to the on_draw event --- @tparam function callback --- callback param - LuaPlayer player - the player that the element was drawn to --- callback param - LuaGuiElement element - the element that was drawn --- callback param - any ... - any other params passed by the draw_to function -Prototype.on_draw = Constructor.event('on_draw') - ---- Registers a callback to the on_style_update event --- @tparam function callback --- callback param - LuaStyle style - the style that was changed and/or needs changing -Prototype.on_style_update = Constructor.event('on_style_update') - ---- Sets the style for the element define --- @tparam string style the style that will be used for this element when drawn --- @tparam[opt] function callback function is called when element is drawn to alter its style --- @treturn self the element define to allow chaining -function Prototype:set_style(style,callback) - self.draw_data.style = style - if callback then - self:on_style_update(callback) - end - return self -end - ---- Sets the element to be drawn inside a nameless flow, can be given a name using a function --- @tparam ?boolean|function state when true a padless flow is created to contain the element --- @treturn self the element define to allow chaining -function Prototype:set_embedded_flow(state) - if state == false or type(state) == 'function' then - self.embedded_flow = state - else - self.embedded_flow = true - end - return self -end - ---- Raises a custom event for this define, any number of params can be given --- @tparam string event_name the name of the event that you want to raise --- @tparam any ... any params that you want to pass to the event --- @treturn number the number of handlers that were registered -function Prototype:raise_event(event_name,...) - local handlers = self.events[event_name] - if handlers then - for _,handler in pairs(handlers) do - handler(...) - end - end - return handlers and #handlers or 0 -end - ---- The main function for defines, when called will draw an instance of this define to the given element --- what is drawn is based on the data in draw_data which is set using other functions --- @tparam LuaGuiElement element the element that the define will draw a instance of its self onto --- @treturn LuaGuiElement the new element that was drawn -function Prototype:draw_to(element,...) - local name = self.name - if element[name] then return end - local player = Game.get_player_by_index(element.player_index) - - if self.pre_authenticator then - if not self.pre_authenticator(player,self.name) then return end - end - - if self.embedded_flow then - local embedded_name - if type(self.embedded_flow) == 'function' then - embedded_name = self.embedded_flow(element,...) - end - element = element.add{type='flow',name=embedded_name} - element.style.padding = 0 - end - - local new_element = element.add(self.draw_data) - - self:raise_event('on_style_update',new_element.style) - - if self.post_authenticator then - new_element.enabled = self.post_authenticator(player,self.name) - end - - if Instances.is_registered(self.name) then - Instances.add_element(self.name,new_element) - end - - self:raise_event('on_draw',player,new_element,...) - - return new_element -end - ---- Gets the value in this elements store, category needed if serializer function used --- @tparam string category[opt] the category to get such as player name or force name --- @treturn any the value that is stored for this define -function Prototype:get_store(category) - if not self.store then return end - return Store.get(self.store,category) -end - ---- Sets the value in this elements store, category needed if serializer function used --- @tparam string category[opt] the category to get such as player name or force name --- @tparam any value the value to set for this define, must be valid for its type ie for checkbox etc --- @treturn boolean true if the value was set -function Prototype:set_store(category,value) - if not self.store then return end - return Store.set(self.store,category,value) -end - ---- Sets the value in this elements store to nil, category needed if serializer function used --- @tparam[opt] string category the category to get such as player name or force name --- @treturn boolean true if the value was set -function Prototype:clear_store(category) - if not self.store then return end - return Store.clear(self.store,category) -end - -return Constructor \ No newline at end of file diff --git a/expcore/gui/test.lua b/expcore/gui/test.lua deleted file mode 100644 index 37cc54f8..00000000 --- a/expcore/gui/test.lua +++ /dev/null @@ -1,663 +0,0 @@ ---[[-- Core Module - Gui - @module Gui - @alias tests -]] - ---- Test. --- This file creates a test gui that is used to test every input method --- note that this does not cover every permutation only features in independence --- for example store in most cases is just by player name, but other store methods are tested with checkbox --- @section test - -local Gui = require 'expcore.gui' --- @dep expcore.gui -local format_chat_colour,table_keys = ext_require('expcore.common','format_chat_colour','table_keys') --- @dep expcore.common -local Colors = require 'resources.color_presets' --- @dep resources.color_presets -local Event = require 'utils.event' --- @dep utils.event -local Store = require 'expcore.store' --- @dep expcore.store - -local tests = {} - ---[[ - Toolbar Tests - > No display - Toolbar button with no display - > With caption - Toolbar button with a caption display - > With icons - Toolbar button with an icon -]] - -Gui.new_toolbar_button('click-1') -:set_post_authenticator(function(player,button_name) - return global.click_one -end) -:on_click(function(player,element) - player.print('CLICK 1') -end) - -Gui.new_toolbar_button('click-2') -:set_caption('Click Two') -:set_post_authenticator(function(player,button_name) - return global.click_two -end) -:on_click(function(player,element) - player.print('CLICK 2') -end) - -Gui.new_toolbar_button('click-3') -:set_sprites('utility/questionmark') -:set_post_authenticator(function(player,button_name) - return global.click_three -end) -:on_click(function(player,element) - player.print('CLICK 3') -end) - ---[[ - Center Frame Tests - > Main test gui - Main test gui triggers all other tests -]] - -local test_gui = -Gui.new_center_frame('gui-test-open') -:set_caption('Open Test Gui') -:set_tooltip('Main test gui triggers all other tests') -:set_post_authenticator(function(player,button_name) - return global.show_test_gui -end) - -:on_creation(function(player,frame) - for test_group_name,test_group in pairs(tests) do - - player.print('Starting tests for: '..format_chat_colour(test_group_name,Colors.cyan)) - - local pass_count = 0 - local test_count = 0 - - local flow = frame.add{ - type='flow', - name=test_group_name, - direction='vertical' - } - - for test_name,test in pairs(test_group) do - local test_function = type(test) == 'function' and test or test.draw_to - test_count = test_count+1 - - local success,err = pcall(test_function,test,flow) - if success then - pass_count = pass_count+1 - else - player.print('Failed Test: '..format_chat_colour(test_name,Colors.red)) - log('Gui Test Failed: '..test_name..' stacktrace:\n'..err) - end - - end - - if pass_count == test_count then - player.print('All tests '..format_chat_colour('passed',Colors.green)..' ('..test_group_name..')') - else - player.print('Passed '..format_chat_colour(pass_count..'/'..test_count,Colors.cyan)..' ('..test_group_name..')') - end - - end -end) - ---[[ - Left Frame Test - > Left frame which holds all online player names, updates when player leaves or joins -]] - -local left_frame = -Gui.new_left_frame('test-left-frame') -:set_caption('Test Left Gui') -:set_tooltip('Left frame which holds all online player names, updates when player leaves or joins') -:set_post_authenticator(function(player,button_name) - return global.show_test_gui -end) - -:set_open_by_default() -:on_creation(function(_player,frame) - for _,player in pairs(game.connected_players) do - frame.add{ - type='label', - caption=player.name - } - end -end) - -Event.add(defines.events.on_player_joined_game,left_frame 'update_all') -Event.add(defines.events.on_player_left_game,left_frame 'update_all') - ---[[ - Popup Test - > Allows opening a popup which contains the players name and tick it was opened -]] - -local test_popup = -Gui.new_popup('test-popup') -:on_creation(function(player,frame) - frame.add{ - type='label', - caption=player.name - } - frame.add{ - type='label', - caption=game.tick - } -end) - -Gui.new_toolbar_button('test-popup-open') -:set_caption('Test Popup') -:set_tooltip('Allows opening a popup which contains the players name and tick it was opened') -:set_post_authenticator(function(player,button_name) - return global.show_test_gui -end) -:on_click(function(player,element) - test_popup(player,300) -end) - ---[[ - Button Tests - > No display - Simple button which has no display - > Caption - Simple button but has a caption on it - > Icons - Button with an icon display plus two icons for hover and select - > Auth - Button which can only be passed when auth is true (press no display to toggle; needs reopen) -]] - -local button_no_display = -Gui.new_button('test-button-no-display') -:set_tooltip('Button no display') -:on_click(function(player,element) - player.print('Button no display') - global.test_auth_button = not global.test_auth_button - player.print('Auth Button auth state: '..tostring(global.test_auth_button)) -end) - -local button_with_caption = -Gui.new_button('test-button-with-caption') -:set_tooltip('Button with caption') -:set_caption('Button Caption') -:on_click(function(player,element) - player.print('Button with caption') -end) - -local button_with_icon = -Gui.new_button('test-button-with-icon') -:set_tooltip('Button with icons') -:set_sprites('utility/warning_icon','utility/warning','utility/warning_white') -:on_click(function(player,element) - player.print('Button with icons') -end) - -local button_with_auth = -Gui.new_button('test-button-with-auth') -:set_tooltip('Button with auth') -:set_post_authenticator(function(player,button_name) - return global.test_auth_button -end) -:on_click(function(player,element) - player.print('Button with auth') -end) - -tests.Buttons = { - ['No display']=button_no_display, - ['Caption']=button_with_caption, - ['Icons']=button_with_icon, - ['Auth']=button_with_auth -} - ---[[ - Checkbox Test - > Local -- Simple checkbox that can toggle - > Game store -- Checkbox which syncs its state between all players - > Force store -- Checkbox which syncs its state with all players on the same force - > Player store -- Checkbox that stores its state between re-draws -]] - -local checkbox_local = -Gui.new_checkbox('test-checkbox-local') -:set_tooltip('Checkbox local') -:set_caption('Checkbox Local') -:on_element_update(function(player,element,state) - player.print('Checkbox local: '..tostring(state)) -end) - -local checkbox_game = -Gui.new_checkbox('test-checkbox-store-game') -:set_tooltip('Checkbox store game') -:set_caption('Checkbox Store Game') -:add_store() -:on_element_update(function(player,element,state) - player.print('Checkbox store game: '..tostring(state)) -end) - -local checkbox_force = -Gui.new_checkbox('test-checkbox-store-force') -:set_tooltip('Checkbox store force') -:set_caption('Checkbox Store Force') -:add_store(Gui.categorize_by_force) -:on_element_update(function(player,element,state) - player.print('Checkbox store force: '..tostring(state)) -end) - -local checkbox_player = -Gui.new_checkbox('test-checkbox-store-player') -:set_tooltip('Checkbox store player') -:set_caption('Checkbox Store Player') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,state) - player.print('Checkbox store player: '..tostring(state)) -end) - -tests.Checkboxes = { - ['Local']=checkbox_local, - ['Game store']=checkbox_game, - ['Force store']=checkbox_force, - ['Player store']=checkbox_player -} - ---[[ - Radiobutton Tests - > Local -- Simple radiobutton that can only be toggled true - > Player store -- Radio button that saves its state between re-draws - > Option set -- A set of radio buttons where only one can be true at a time -]] - -local radiobutton_local = -Gui.new_radiobutton('test-radiobutton-local') -:set_tooltip('Radiobutton local') -:set_caption('Radiobutton Local') -:on_element_update(function(player,element,state) - player.print('Radiobutton local: '..tostring(state)) -end) - -local radiobutton_player = -Gui.new_radiobutton('test-radiobutton-store') -:set_tooltip('Radiobutton store') -:set_caption('Radiobutton Store') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,state) - player.print('Radiobutton store: '..tostring(state)) -end) - -local radiobutton_option_set = -Gui.new_radiobutton_option_set(function(value,category) - game.print('Radiobutton option set for: '..category..' is now: '..tostring(value)) -end,Gui.categorize_by_player) - -local radiobutton_option_one = -Gui.new_radiobutton('test-radiobutton-option-one') -:set_tooltip('Radiobutton option set') -:set_caption('Radiobutton Option One') -:add_as_option(radiobutton_option_set,'One') -:on_element_update(function(player,element,state) - player.print('Radiobutton option one: '..tostring(state)) -end) - -local radiobutton_option_two = -Gui.new_radiobutton('test-radiobutton-option-two') -:set_tooltip('Radiobutton option set') -:set_caption('Radiobutton Option Two') -:add_as_option(radiobutton_option_set,'Two') -:on_element_update(function(player,element,state) - player.print('Radiobutton option two: '..tostring(state)) -end) - -local radiobutton_option_three = -Gui.new_radiobutton('test-radiobutton-option-three') -:set_tooltip('Radiobutton option set') -:set_caption('Radiobutton Option Three') -:add_as_option(radiobutton_option_set,'Three') -:on_element_update(function(player,element,state) - player.print('Radiobutton option three: '..tostring(state)) -end) - -tests.Radiobuttons = { - ['Local']=radiobutton_local, - ['Player store']=radiobutton_player, - ['Option set']=function(self,frame) - Gui.draw_option_set(radiobutton_option_set,frame) - end -} - ---[[ - Dropdown Test - > Local static general -- Simple dropdown with all static options and general handler - > Player startic general -- Dropdown with all static options and general handler and stores option between re-draws - > Local static case -- Dropdown with all static options but case handlers and a general handler - > Player static case -- Dropdown with all static options but case handlers and a general handler and stores option between re-draws - > Local dynamic -- Dropdown with one static option with the reset generated by a function - > Player dynamic -- Dropdown with one static option with the reset generated by a function and stores option between re-draws -]] - -local dropdown_local_static_general = -Gui.new_dropdown('test-dropdown-local-static-general') -:set_tooltip('Dropdown local static general') -:add_options('One','Two','Three','Four') -:on_element_update(function(player,element,value) - player.print('Dropdown local static general: '..tostring(value)) -end) - -local dropdown_player_static_general = -Gui.new_dropdown('test-dropdown-store-static-general') -:set_tooltip('Dropdown store static general') -:add_options('One','Two','Three','Four') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Dropdown store static general: '..tostring(value)) -end) - -local function print_option_selected_1(player,element,value) - player.print('Dropdown local static case (case): '..tostring(value)) -end - -local dropdown_local_static_case = -Gui.new_dropdown('test-dropdown-local-static-case') -:set_tooltip('Dropdown local static case') -:add_options('One','Two') -:add_option_callback('One',print_option_selected_1) -:add_option_callback('Two',print_option_selected_1) -:add_option_callback('Three',print_option_selected_1) -:add_option_callback('Four',print_option_selected_1) -:on_element_update(function(player,element,value) - player.print('Dropdown local static case (general): '..tostring(value)) -end) - -local function print_option_selected_2(player,element,value) - player.print('Dropdown store static case (case): '..tostring(value)) -end - -local dropdown_player_static_case = -Gui.new_dropdown('test-dropdown-store-static-case') -:set_tooltip('Dropdown store static case') -:add_store(Gui.categorize_by_player) -:add_options('One','Two') -:add_option_callback('One',print_option_selected_2) -:add_option_callback('Two',print_option_selected_2) -:add_option_callback('Three',print_option_selected_2) -:add_option_callback('Four',print_option_selected_2) -:on_element_update(function(player,element,value) - player.print('Dropdown store static case (general): '..tostring(value)) -end) - -local dropdown_local_dynamic = -Gui.new_dropdown('test-dropdown-local-dynamic') -:set_tooltip('Dropdown local dynamic') -:add_options('Static') -:add_dynamic(function(player,element) - return table_keys(Colors) -end) -:on_element_update(function(player,element,value) - player.print('Dropdown local dynamic: '..tostring(value)) -end) - -local dropdown_player_dynamic = -Gui.new_dropdown('test-dropdown-store-dynamic') -:set_tooltip('Dropdown store dynamic') -:add_options('Static') -:add_dynamic(function(player,element) - return table_keys(Colors) -end) -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Dropdown store dynamic: '..tostring(value)) -end) - -tests.Dropdowns = { - ['Local static general']=dropdown_local_static_general, - ['Player startic general']=dropdown_player_static_general, - ['Local static case']=dropdown_local_static_case, - ['Player static case']=dropdown_player_static_case, - ['Local dynamic general']=dropdown_local_dynamic, - ['Player dynamic general']=dropdown_player_dynamic -} - ---[[ - List Box Tests - > Local -- A list box with all static options and general handler - > Store -- A list box with all static options and general handler and stores options between re-draws -]] - -local list_box_local = -Gui.new_list_box('test-list-box-local') -:set_tooltip('List box local') -:add_options('One','Two','Three','Four') -:on_element_update(function(player,element,value) - player.print('Dropdown local: '..tostring(value)) -end) - -local list_box_player = -Gui.new_list_box('test-list-box-store') -:set_tooltip('List box store') -:add_options('One','Two','Three','Four') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Dropdown store: '..tostring(value)) -end) - -tests["List Boxes"] = { - ['Local']=list_box_local, - ['Player']=list_box_player -} - ---[[ - Slider Tests - > Local default -- Simple slider with default range - > Store default -- Slider with default range that stores value between re-draws - > Static range -- Simple slider with a static range - > Dynamic range -- Slider with a dynamic range - > Local label -- Simple slider with default range which has a label - > Store label -- Slider with default range which has a label and stores value between re-draws -]] - -local slider_local_default = -Gui.new_slider('test-slider-local-default') -:set_tooltip('Slider local default') -:on_element_update(function(player,element,value,percent) - player.print('Slider local default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - - -local slider_player_default = -Gui.new_slider('test-slider-store-default') -:set_tooltip('Slider store default') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value,percent) - player.print('Slider store default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -local slider_static = -Gui.new_slider('test-slider-static-range') -:set_tooltip('Slider static range') -:set_range(5,50) -:on_element_update(function(player,element,value,percent) - player.print('Slider static range: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -local slider_dynamic = -Gui.new_slider('test-slider-dynamic-range') -:set_tooltip('Slider dynamic range') -:set_range(function(player,element) - return player.index - 5 -end,function(player,element) - return player.index + 4 -end) -:on_element_update(function(player,element,value,percent) - player.print('Slider dynamic range: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -local label_slider_local = -Gui.new_slider('test-slider-local-label') -:set_tooltip('Slider local label') -:enable_auto_draw_label() -:on_element_update(function(player,element,value,percent) - player.print('Slider local label: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -local label_slider_player = -Gui.new_slider('test-slider-store-label') -:set_tooltip('Slider store label') -:enable_auto_draw_label() -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value,percent) - player.print('Slider store label: '..tostring(math.round(value))..' '..tostring(math.round(percent,1))) -end) - -tests.Sliders = { - ['Local default']=slider_local_default, - ['Player default']=slider_player_default, - ['Static range']=slider_static, - ['Dynamic range']=slider_dynamic, - ['Local label']=function(self,frame) - local flow = frame.add{type='flow'} - label_slider_local:draw_to(flow) - end, - ['Player label']=function(self,frame) - local flow = frame.add{type='flow'} - label_slider_player:draw_to(flow) - end -} - ---[[ - Text Tests - > Local field -- Simple text field - > Store field -- Test field that stores text between re-draws - > Local box -- Simple text box - > Wrap box -- Text box which has word wrap and selection disabled -]] - -local text_filed_local = -Gui.new_text_filed('test-text-field-local') -:set_tooltip('Text field local') -:on_element_update(function(player,element,value) - player.print('Text field local: '..value) -end) - -local text_filed_store = -Gui.new_text_filed('test-text-field-store') -:set_tooltip('Text field store') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Text field store: '..value) -end) - -local text_box_local = -Gui.new_text_box('test-text-box-local') -:set_tooltip('Text box local') -:on_element_update(function(player,element,value) - player.print('Text box local: '..value) -end) - -local text_box_wrap = -Gui.new_text_box('test-text-box-wrap') -:set_tooltip('Text box wrap') -:set_selectable(false) -:set_word_wrap() -:on_element_update(function(player,element,value) - player.print('Text box wrap: '..value) -end) - -tests.Texts = { - ['Local field']=text_filed_local, - ['Store field']=text_filed_store, - ['Local box']=text_box_local, - ['Wrap box']=text_box_wrap -} - ---[[ - Elem Button Tests - > Local -- Simple elem button - > Default -- Simple elem button which has a default value - > Function -- Elem button which has a dynamic default - > Store -- Elem button which stores its value between re-draws -]] - -local elem_local = -Gui.new_elem_button('test-elem-local') -:set_tooltip('Elem') -:set_type('item') -:on_element_update(function(player,element,value) - player.print('Elem: '..value) -end) - -local elem_default = -Gui.new_elem_button('test-elem-default') -:set_tooltip('Elem default') -:set_type('item') -:set_default('iron-plate') -:on_element_update(function(player,element,value) - player.print('Elem default: '..value) -end) - -local elem_function = -Gui.new_elem_button('test-elem-function') -:set_tooltip('Elem function') -:set_type('item') -:set_default(function(player,element) - return 'iron-plate' -end) -:on_element_update(function(player,element,value) - player.print('Elem function: '..value) -end) - -local elem_store = -Gui.new_elem_button('test-elem-store') -:set_tooltip('Elem store') -:set_type('item') -:add_store(Gui.categorize_by_player) -:on_element_update(function(player,element,value) - player.print('Elem store: '..value) -end) - -tests["Elem Buttons"] = { - ['Local']=elem_local, - ['Default']=elem_default, - ['Function']=elem_function, - ['Store']=elem_store -} - ---[[ - Progress bar tests - > Simple -- Progress bar that fills every 2 seconds - > Store -- Progress bar that fills every 5 seconds with synced value - > Reverse -- Progress bar that decreases every 2 seconds -]] - -local progressbar_one = -Gui.new_progressbar('test-prog-one') -:set_default_maximum(120) -:on_complete(function(player,element,reset_element) - reset_element() -end) - -local progressbar_two = -Gui.new_progressbar('test-prog-one') -:set_default_maximum(300) -:add_store(Gui.categorize_by_force) -:on_complete(function(player,element,reset_element) - reset_element() -end) -:on_store_complete(function(category,reset_store) - reset_store() -end) - -local progressbar_three = -Gui.new_progressbar('test-prog-one') -:set_default_maximum(120) -:use_count_down() -:on_complete(function(player,element,reset_element) - reset_element() -end) - -Event.add(defines.events.on_tick,function() - progressbar_one:increment() - progressbar_three:decrement() - local categories = Store.get(progressbar_two.store) or {} - for category,_ in pairs(categories) do - progressbar_two:increment(1,category) - end -end) - -tests["Progress Bars"] = { - ['Simple']=progressbar_one, - ['Store']=progressbar_two, - ['Reverse']=progressbar_three -} \ No newline at end of file From f7cff8b2361825ecb8f6e6d88adf2cf64c53b6d5 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 24 Oct 2019 01:44:41 +0100 Subject: [PATCH 04/81] Task List Updated --- config/_file_loader.lua | 4 +- config/tasks.lua | 11 +- docs/addons/Advanced-Start.html | 2 +- docs/addons/Chat-Popups.html | 2 +- docs/addons/Chat-Reply.html | 2 +- docs/addons/Compilatron.html | 2 +- docs/addons/Damage-Popups.html | 2 +- docs/addons/Death-Logger.html | 2 +- docs/addons/Discord-Alerts.html | 2 +- docs/addons/Player-Colours.html | 2 +- docs/addons/Pollution-Grading.html | 2 +- docs/addons/Scorched-Earth.html | 2 +- docs/addons/Spawn-Area.html | 2 +- docs/commands/Admin-Chat.html | 2 +- docs/commands/Bonus.html | 2 +- docs/commands/Cheat-Mode.html | 2 +- docs/commands/Clear-Inventory.html | 2 +- docs/commands/Debug.html | 2 +- docs/commands/Find.html | 2 +- docs/commands/Help.html | 2 +- docs/commands/Home.html | 2 +- docs/commands/Interface.html | 2 +- docs/commands/Jail.html | 2 +- docs/commands/Kill.html | 2 +- docs/commands/Me.html | 2 +- docs/commands/Rainbow.html | 2 +- docs/commands/Repair.html | 2 +- docs/commands/Reports.html | 2 +- docs/commands/Roles.html | 2 +- docs/commands/Spawn.html | 2 +- docs/commands/Tag.html | 2 +- docs/commands/Teleport.html | 2 +- docs/commands/Warnings.html | 2 +- docs/configs/Advanced-Start.html | 2 +- docs/configs/Bonuses.html | 2 +- docs/configs/Chat-Reply.html | 2 +- docs/configs/Commands-Auth-Admin.html | 2 +- docs/configs/Commands-Auth-Roles.html | 2 +- .../Commands-Auth-Runtime-Disable.html | 2 +- docs/configs/Commands-Parse-Roles.html | 2 +- docs/configs/Commands-Parse.html | 2 +- docs/configs/Compilatron.html | 2 +- docs/configs/Death-Logger.html | 2 +- docs/configs/Discord-Alerts.html | 2 +- docs/configs/File-Loader.html | 2 +- docs/configs/Permission-Groups.html | 2 +- docs/configs/Player-List.html | 2 +- docs/configs/Pollution-Grading.html | 2 +- docs/configs/Popup-Messages.html | 2 +- docs/configs/Preset-Player-Colours.html | 2 +- docs/configs/Repair.html | 2 +- docs/configs/Rockets.html | 2 +- docs/configs/Roles.html | 2 +- docs/configs/Science.html | 2 +- docs/configs/Scorched-Earth.html | 2 +- docs/configs/Spawn-Area.html | 2 +- docs/configs/Tasks.html | 35 +- docs/configs/Warnings.html | 2 +- docs/configs/Warps.html | 2 +- docs/control/Jail.html | 2 +- docs/control/Production.html | 2 +- docs/control/Reports.html | 2 +- docs/control/Rockets.html | 2 +- docs/control/Tasks.html | 2 +- docs/control/Warnings.html | 2 +- docs/control/Warps.html | 2 +- docs/core/Commands.html | 2 +- docs/core/Common-Library.html | 2 +- docs/core/Gui.html | 875 +++++++++++++++++- docs/core/Permissions-Groups.html | 2 +- docs/core/Roles.html | 2 +- docs/core/Store.html | 29 +- docs/core/Sudo.html | 2 +- docs/guis/Player-List.html | 2 +- docs/guis/Rocket-Info.html | 2 +- docs/guis/Science-Info.html | 2 +- docs/guis/Task-List.html | 156 +++- docs/guis/Warps-List.html | 2 +- docs/index.html | 2 +- docs/modules/control.html | 2 +- .../utils.alien_evolution_progress.html | 2 +- docs/modules/utils.core.html | 2 +- docs/modules/utils.debug.html | 2 +- docs/modules/utils.dump_env.html | 2 +- docs/modules/utils.event.html | 2 +- docs/modules/utils.event_core.html | 2 +- docs/modules/utils.math.html | 2 +- docs/modules/utils.recipe_locker.html | 2 +- docs/modules/utils.state_machine.html | 2 +- docs/modules/utils.table.html | 2 +- docs/modules/utils.task.html | 2 +- docs/modules/utils.timestamp.html | 2 +- docs/topics/license.html | 2 +- docs/topics/readme.md.html | 2 +- expcore/gui.lua | 391 ++++++-- expcore/store.lua | 34 +- modules/control/tasks.lua | 2 +- modules/gui/task-list.lua | 624 ++++++++----- 98 files changed, 1849 insertions(+), 488 deletions(-) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 44f73644..b7ccbd92 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -42,15 +42,13 @@ return { --'modules.gui.rocket-info', --'modules.gui.science-info', --'modules.gui.warp-list', - --'modules.gui.task-list', + 'modules.gui.task-list', --'modules.gui.player-list', --'modules.commands.debug', - 'expcore.gui', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.expcore-commands.auth_roles', -- commands must be allowed via the role config 'config.expcore-commands.auth_runtime_disable', -- allows commands to be enabled and disabled during runtime 'config.permission_groups', -- loads some predefined permission groups 'config.roles', -- loads some predefined roles - --'expcore.gui.test' -- loads multiple gui defines to test the gui system } \ No newline at end of file diff --git a/config/tasks.lua b/config/tasks.lua index 95165ee0..994acff8 100644 --- a/config/tasks.lua +++ b/config/tasks.lua @@ -2,8 +2,11 @@ -- @config Tasks return { - any_user_can_add_new_task = true, --- @setting any_user_can_add_new_task when false only people with edit permission can make new reports - user_can_edit_own_tasks = true, --- @setting user_can_edit_own_tasks when false only people with edit permission can edit reports - only_admins_can_edit = false, --- @setting only_admins_can_edit true will hide the edit and delete buttons from non (game) admins - edit_tasks_role_permission = 'gui/task-list/edit' --- @setting edit_tasks_role_permission value used with custom permission system + -- values can be all, admin, expcore.roles, none + allow_add_task = 'all', --- @setting allow_add_task dictates who is allowed to add new tasks; values: all, admin, expcore.roles, none + expcore_roles_add_permission = 'gui/task-list/add', --- @setting expcore_roles_add_permission if expcore.roles is used then this is the required permission + -- values can be all, admin, expcore.roles, none + allow_edit_task = 'expcore.roles', --- @setting allow_edit_task dictates who is allowed to edit existing tasks; values: all, admin, expcore.roles, none + expcore_roles_edit_permission = 'gui/task-list/edit', --- @setting expcore_roles_edit_permission if expcore.roles is used then this is the required permission + user_can_edit_own_tasks = true --- @settings if true then the user who made the task can edit it regardless of the allow_edit_task setting } \ No newline at end of file diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index 4871b8c9..4fc1a161 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -348,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index 3efd7ce5..31bafcd7 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index c5d3cfc4..740ed70e 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index 57a4a065..6fb21b76 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index f42f7dee..4f5b7ae2 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index 6f540b7d..8983690a 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index e9f689ac..e0085ca5 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -460,7 +460,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index 06a8e29a..5de171a9 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index 806b86fd..08b4fc10 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index bcfab620..dcc7f831 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 7f9b0c0a..54a470ef 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 0a936c4e..894d9fd7 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index e7e42cdd..bb480f1c 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -500,7 +500,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index 53b422c3..11a3faa5 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -361,7 +361,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index 17ef4f9d..fb090d39 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index 880bb18e..1960d836 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -365,7 +365,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index f8d25958..ac910592 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index b7d54d80..5488f96a 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index d279fe65..371db9aa 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -458,7 +458,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index 8458181f..ef15886c 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 214140d6..5f07e558 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -611,7 +611,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index 421f28a9..a892d1aa 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index a31f9a45..c6e4fa94 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index 439294a8..d7dd8363 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index 98e6942b..6225e155 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -321,7 +321,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index 1957df69..2c739395 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index 0f9bc8b1..d94c73f6 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -557,7 +557,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index f72dbee2..24f01cf0 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index 60783e88..2dd125fd 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -443,7 +443,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index 353738fe..8a4262f3 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -484,7 +484,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index d33d1547..884b4a42 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -569,7 +569,7 @@ generated by LDoc diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index 94b0896f..7d0e5d3d 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -506,7 +506,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index e7bb072a..9612f09e 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index ee1e2dd2..021275cd 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -485,7 +485,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index 157b0311..dd7c7ddb 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -294,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index 59a9ed26..689ef12e 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index b299522c..9f3db256 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index 42155a89..de12ef31 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index 8128d402..76a3b440 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -338,7 +338,7 @@ see ./expcore/commands.lua for more details

    generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index 0932f52e..d3162a9e 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index 1e635943..38e0eee2 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index 7214429c..f9d7156b 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 21a5ee90..9331d05b 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -240,7 +240,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index 1ab7621e..3deb9a8e 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -295,7 +295,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index bd67fe6b..2d91ee39 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -812,7 +812,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index d775b006..64fa59aa 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index 02436326..f648a0f5 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index 2d2a05a7..267b19c9 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -324,7 +324,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index 5141d747..0449a9f1 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index f011e724..8d50f302 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -834,7 +834,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index e435071a..33b1ba00 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -292,7 +292,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index bea29f94..6aa0aa00 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index f271bf65..df64e68c 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index a1a68698..0cd0d9f7 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -744,7 +744,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index e4f9760a..8a8ae44b 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -241,16 +241,16 @@ - any_user_can_add_new_task + allow_add_task - user_can_edit_own_tasks + expcore_roles_add_permission - only_admins_can_edit + allow_edit_task - edit_tasks_role_permission + expcore_roles_edit_permission @@ -264,15 +264,15 @@
    - # - any_user_can_add_new_task + # + allow_add_task

    -

    when false only people with edit permission can make new reports

    +

    dictates who is allowed to add new tasks; values: all, admin, expcore.roles, none

    @@ -291,15 +291,16 @@
    - # - user_can_edit_own_tasks + # + expcore_roles_add_permission

    -

    when false only people with edit permission can edit reports

    +

    if expcore.roles is used then this is the required permission + values can be all, admin, expcore.roles, none

    @@ -318,15 +319,15 @@
    - # - only_admins_can_edit + # + allow_edit_task

    -

    true will hide the edit and delete buttons from non (game) admins

    +

    dictates who is allowed to edit existing tasks; values: all, admin, expcore.roles, none

    @@ -345,15 +346,15 @@
    - # - edit_tasks_role_permission + # + expcore_roles_edit_permission

    -

    value used with custom permission system

    +

    if expcore.roles is used then this is the required permission

    @@ -384,7 +385,7 @@ generated by LDoc
    diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index 751529ef..2a237eb2 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -355,7 +355,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index 3840e9b9..5ef899b2 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -684,7 +684,7 @@ generated by LDoc diff --git a/docs/control/Jail.html b/docs/control/Jail.html index 8ed47a2e..a809745f 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -1208,7 +1208,7 @@ generated by LDoc diff --git a/docs/control/Production.html b/docs/control/Production.html index 2cac6422..12a57823 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -1329,7 +1329,7 @@ generated by LDoc diff --git a/docs/control/Reports.html b/docs/control/Reports.html index 16391654..a239a42c 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -1110,7 +1110,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index 831e5343..a11e1edc 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -984,7 +984,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index c68201ec..cbe14682 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -998,7 +998,7 @@ Tasks.update_task(task_id,'We need more iron!',game. generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index ff7f7802..84f5e53c 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -1465,7 +1465,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index 7791b32f..16a7f9de 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -1563,7 +1563,7 @@ Warps.make_warp_tag(warp_id) generated by LDoc diff --git a/docs/core/Commands.html b/docs/core/Commands.html index 075e5bb8..545ac82f 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -1972,7 +1972,7 @@ generated by LDoc diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index caba804c..fedadfc1 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -2746,7 +2746,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Gui.html b/docs/core/Gui.html index 74601e95..c438edc4 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -48,6 +48,7 @@ + @@ -214,6 +215,7 @@ + @@ -245,34 +247,58 @@

    Usage

    -- Defining a button that prints the player's name
     local example_button =
    -Gui.new_element{
    +Gui.element{
         type = 'button',
         caption = 'Example Button'
     }
    -:on_click(function(event)
    -    local player = event.player
    +:on_click(function(player,element,event)
         player.print(player.name)
     end)
    -
    -- Defining using a custom function
    +    
    -- Defining a button with a custom style
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button'
    +}
    +:style{
    +    height = 25,
    +    width = 100
    +}
    +:on_click(function(player,element,event)
    +    player.print(player.name)
    +end)
    +
    -- Defining a button using a custom function
     local example_flow_with_button =
    -Gui.new_element(function(event_trigger,parent)
    -    local flow =
    +Gui.element(function(event_trigger,parent)
    +    -- Add the flow the button is in
    +    local flow =
         parent.add{
             name = 'example_flow',
             type = 'flow'
         }
     
    -    local element =
    +    -- Get the players name
    +    local player = game.players[parent.player_index]
    +    local player_name = player.name
    +
    +    -- Add the button
    +    local element =
         flow.add{
             name = event_trigger,
             type = 'button',
    -        caption = 'Example Button'
    +        caption = 'Example Button: '..player_name
         }
     
    -    return element
    +    -- Set the style of the button
    +    local style = element.style
    +    style.height = 25
    +    style.width = 100]
    +    style.font_color = player.color
    +
    +    -- Return the element
    +    return element
     end)
    -:on_click(function(event)
    -    local player = event.player
    +:on_click(function(player,element,event)
         player.print(player.name)
     end)
    -- Drawing an element
    @@ -321,7 +347,7 @@ Gui.new_element(function(event_trigger,parent)
         
         
         _prototype_element
    -    The element prototype which is returned from Gui.new_element
    +    The element prototype which is returned from Gui.element
         
         
         _mt_element
    @@ -348,10 +374,14 @@ Gui.new_element(function(event_trigger,parent)
         
         
         
    -    new_element(element_define)
    +    element(element_define)
         Base function used to define new elements, can be used with a table or with a function
         
         
    +    Gui._prototype_element:style(style_define)
    +    Extension of Gui.element when using the table method, values applied after the element is drawn
    +    
    +    
         Gui._prototype_element:add_to_top_flow([authenticator])
         Adds an element to be drawn to the top flow when a player joins
         
    @@ -428,6 +458,10 @@ Gui.new_element(function(event_trigger,parent)
         Button which toggles the top flow elements
         
         
    +    top_flow_button_style
    +    The style that should be used for buttons on the top flow
    +    
    +    
         get_top_flow(player)
         Gets the flow which contains the elements for the top flow
         
    @@ -465,6 +499,42 @@ Gui.new_element(function(event_trigger,parent)
         
         
         
    +    
    +    
    +    

    Helper Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    get_player_from_element(element)Get the player that owns a gui element
    toggle_enabled_state(element[, state])Will toggle the enabled state of an element or set it to the one given
    toggle_visible_state(element[, state])Will toggle the visible state of an element or set it to the one given
    destroy_if_valid(element)Destory a gui element without causing any errors, likly if the element may have already been removed
    alignment(parent[, horizontal_align='right'][, vertical_align='center'][, name='alignment'])Draw a flow that has custom element alignments, default is right align
    scroll_table(parent, height, column_count[, name='scroll'])Draw a scroll pane that has a table inside of it
    header(parent, caption[, tooltip][, add_alignment=false][, name='header'])Used to add a header to a frame, this has the option for a custom right alignment flow for buttons

    @@ -643,7 +713,7 @@ Gui.new_element(function(event_trigger,parent)
    -

    The element prototype which is returned from Gui.new_element

    +

    The element prototype which is returned from Gui.element

    @@ -764,8 +834,8 @@ Gui.new_element(function(event_trigger,parent)
    - # - new_element(element_define) + # + element(element_define)
    @@ -818,27 +888,115 @@ Gui.new_element(function(event_trigger,parent) Usage:
    -- Defining an element with a table
     local example_button =
    -Gui.new_element{
    +Gui.element{
         type = 'button',
         caption = 'Example Button'
     }
    -- Defining an element with a function
     local example_flow_with_button =
    -Gui.new_element(function(event_trigger,parent)
    -    local flow =
    +Gui.element(function(event_trigger,parent,...)
    +    -- Add the flow the button is in
    +    local flow =
         parent.add{
             name = 'example_flow',
             type = 'flow'
         }
     
    -    local element =
    +    -- Add the button
    +    local element =
         flow.add{
             name = event_trigger,
             type = 'button',
             caption = 'Example Button'
         }
     
    -    return element
    +    -- Set the style of the button
    +    local style = element.style
    +    style.height = 25
    +    style.width = 100
    +
    +    -- Return the element
    +    return element
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:style(style_define) +
    +
    +
    +
    + +

    Extension of Gui.element when using the table method, values applied after the element is drawn

    +

    + + + Parameters: + +
      + + + + + +
    • + + style_define + + : + + (table or function) + + used to define how the style is applied, using a table is the simplist way of doing this + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the new element define that is used to register events to this element +
    • +
    + + + + + + + + Usage: +
    -- Setting the height and width of the example button
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button'
    +}
    +:style{
    +    height = 25,
    +    width = 100
    +}
    +
    -- Using a function to set the style
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button'
    +}
    +:style(function(style,element,...)
    +    local player = game.players[element.player_index]
    +    style.height = 25
    +    style.width = 100
    +    style.font_color = player.color
     end)
    @@ -884,6 +1042,13 @@ Gui.new_element(function(event_trigger,parent) + Returns: +
      +
    • + (table) + the new element define that is used to register events to this element +
    • +
    @@ -941,6 +1106,13 @@ Gui.new_element(function(event_trigger,parent) + Returns: +
      +
    • + (table) + the new element define that is used to register events to this element +
    • +
    @@ -1568,6 +1740,33 @@ Gui.new_element(function(event_trigger,parent) + + + + + + +
    +
    +
    +
    + # + top_flow_button_style +
    +
    +
    +
    + +

    The style that should be used for buttons on the top flow

    +

    + + + + + + + + @@ -2004,6 +2203,638 @@ Gui.new_element(function(event_trigger,parent) Gui.toggle_top_flow(game.player,example_flow_with_button,true)
    +
    +
    +

    Helper Functions

    +
    +
    +
    +
    + # + get_player_from_element(element) +
    +
    +
    +
    + +

    Get the player that owns a gui element

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element that you want to get the owner of + +
    • + + +
    + + + + + Returns: +
      +
    • + (LuaPlayer) + the player that owns this element +
    • +
    + + + + + + + + Usage: +
    -- Geting the owner of an element
    +local player = Gui.get_player_from_element(element)
    + + +
    +
    +
    +
    + # + toggle_enabled_state(element[, state]) +
    +
    +
    +
    + +

    Will toggle the enabled state of an element or set it to the one given

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element that you want to toggle the state of + +
    • + + + + + +
    • + + state + + : + + (boolean) + + the state that you want to set + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new enabled state that the element has +
    • +
    + + + + + + + + Usage: +
    -- Toggling the the enabled state
    +local new_enabled_state = Gui.toggle_enabled_state(element)
    + + +
    +
    +
    +
    + # + toggle_visible_state(element[, state]) +
    +
    +
    +
    + +

    Will toggle the visible state of an element or set it to the one given

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element that you want to toggle the state of + +
    • + + + + + +
    • + + state + + : + + (boolean) + + the state that you want to set + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new visible state that the element has +
    • +
    + + + + + + + + Usage: +
    -- Toggling the the visible state
    +local new_visible_state = Gui.toggle_visible_state(element)
    + + +
    +
    +
    +
    + # + destroy_if_valid(element) +
    +
    +
    +
    + +

    Destory a gui element without causing any errors, likly if the element may have already been removed

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element that you want to remove + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if the element was valid and has been removed +
    • +
    + + + + + + + + Usage: +
    -- Likely use case for element not existing
    +Gui.destroy_if_valid(element[child_name])
    + + +
    +
    +
    +
    + # + alignment(parent[, horizontal_align='right'][, vertical_align='center'][, name='alignment']) +
    +
    +
    +
    + +

    Draw a flow that has custom element alignments, default is right align

    +

    + + + Parameters: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element that the alignment flow will be added to + +
    • + + + + + +
    • + + horizontal_align + + : + + (string) + + the horizontal alignment of the elements in the flow + + (default: 'right') +
    • + + + + + +
    • + + vertical_align + + : + + (string) + + the vertical alignment of the elements in the flow + + (default: 'center') +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the alignment flow + + (default: 'alignment') +
    • + + +
    + + + + + Returns: + + + + + + + + + Usage: +
    -- Adding a right align flow
    +local alignment = Gui.alignment(element,'example_right_alignment')
    +
    -- Adding a horizontal center and top align flow
    +local alignment = Gui.alignment(element,'example_center_top_alignment','center','top')
    + + +
    +
    +
    +
    + # + scroll_table(parent, height, column_count[, name='scroll']) +
    +
    +
    +
    + +

    Draw a scroll pane that has a table inside of it

    +

    + + + Parameters: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element that the scroll table will be added to + +
    • + + + + + +
    • + + height + + : + + (number) + + the maximum height for the scroll pane + +
    • + + + + + +
    • + + column_count + + : + + (number) + + the number of columns that the table will have + +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the scroll pane that is added, the table is always called 'table' + + (default: 'scroll') +
    • + + +
    + + + + + Returns: + + + + + + + + + Usage: +
    -- Adding a scroll table with max height of 200 and column count of 3
    +local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3)
    + + +
    +
    +
    +
    + # + header(parent, caption[, tooltip][, add_alignment=false][, name='header']) +
    +
    +
    +
    + +

    Used to add a header to a frame, this has the option for a custom right alignment flow for buttons

    +

    + + + Parameters: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element that the header will be added to + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the header + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the header + + (optional) +
    • + + + + + +
    • + + add_alignment + + : + + (boolean) + + when true an alignment flow will be added for buttons + + (default: false) +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the header that is being added, the alignment is always called 'alignment' + + (default: 'header') +
    • + + +
    + + + + + Returns: +
      +
    • + (LuaGuiElement) + either the header or the header alignment if add_alignment is true +
    • +
    + + + + + + + + Usage: +
    -- Adding a custom header
    +local header_alignment = Gui.header(
    +    element,
    +    'example_header',
    +    'Example Caption',
    +    'Example Tooltip',
    +    true
    +)
    + +
    @@ -2020,7 +2851,7 @@ Gui.new_element(function(event_trigger,parent) generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index d684f92e..13bacb25 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -1432,7 +1432,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index 2e261b19..cfb25893 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -3152,7 +3152,7 @@ generated by LDoc diff --git a/docs/core/Store.html b/docs/core/Store.html index c977f109..f5eb98bb 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -262,7 +262,7 @@ Store.set(scenario_diffculty,'hard') end) -- When any key in the store is changed this function will trigger -Store.watch(player_scores,function(value,key) +Store.watch(player_scores,function(value,key,old_value) game.print(key..' now has a score of '..value) end) @@ -370,7 +370,7 @@ Store.set(player_scores,game.player,10) Used to trigger watcher functions, this may be used to trigger them if you did not use Store.update or Store.set - raw_trigger(store[, key][, value]) + raw_trigger(store[, key][, value][, old_value]) Used to trigger watcher functions, the value and key are passed directly to the watchers regardless if the value is correct @@ -791,7 +791,7 @@ Store.set(player_scores,game.player,10) end) -- Register the watcher so that when we change the value the message is printed -Store.watch(player_scores,function(value,key) +Store.watch(player_scores,function(value,key,old_value) game.print(key..' now has a score of '..value) end) @@ -1361,7 +1361,7 @@ Store.set(player_scores,game.player,10)
    # - raw_trigger(store[, key][, value]) + raw_trigger(store[, key][, value][, old_value])
    @@ -1426,6 +1426,23 @@ Store.set(player_scores,game.player,10) + + + +
  • + + old_value + + : + + (any) + + the old value that was at this key or store often the same if value is a table, passed directly to the watcher + + (optional) +
  • + + @@ -1445,7 +1462,7 @@ Store.set(player_scores,game.player,10) -- Trigger the watchers with a fake change of diffculty -- This is mostly used internally but it can be useful in other cases -Store.raw_trigger(scenario_diffculty,nil,'normal')
    +Store.raw_trigger(scenario_diffculty,nil,'normal','normal')
    @@ -1464,7 +1481,7 @@ Store.set(player_scores,game.player,10) generated by LDoc diff --git a/docs/core/Sudo.html b/docs/core/Sudo.html index ea78d5a3..9a0a180b 100644 --- a/docs/core/Sudo.html +++ b/docs/core/Sudo.html @@ -544,7 +544,7 @@ generated by LDoc diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index d1ca6a0e..e0e633ba 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -626,7 +626,7 @@ generated by LDoc diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index 21253ddc..5714de34 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -629,7 +629,7 @@ generated by LDoc diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 3dc31aa5..12c80988 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -449,7 +449,7 @@ generated by LDoc diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index 454a6901..a16009c7 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -271,27 +271,43 @@ add_new_task - Button in the header to add a new task + Button displayed in the ehader bar, used to add a new task confirm_edit - Used to save changes to a task + Button displayed next to tasks which the user is currently editing, used to save changes cancel_edit - Used to cancel any changes you made to a task + Button displayed next to tasks which the user is currently editing, used to discard changes discard_task - Removes the task from the list + Button displayed next to tasks which the user is can edit, used to delete a task from the list edit_task - Opens edit mode for the task + Button displayed next to tasks which the user is can edit, used to start editing a task - task_list - Registers the task list + add_task_base + Set of three elements which make up each row of the task table + + + task_label + Default state for a task, contains only a label with the task message + + + task_editing + Editing state for a task, contrins a text field and the two edit buttons + + + task_list_container + Main task list container for the left flow + + + task_list_toggle + Button on the top flow used to toggle the task list container @@ -465,7 +481,7 @@
    -

    Button in the header to add a new task

    +

    Button displayed in the ehader bar, used to add a new task

    @@ -492,7 +508,7 @@
    -

    Used to save changes to a task

    +

    Button displayed next to tasks which the user is currently editing, used to save changes

    @@ -519,7 +535,7 @@
    -

    Used to cancel any changes you made to a task

    +

    Button displayed next to tasks which the user is currently editing, used to discard changes

    @@ -546,7 +562,7 @@
    -

    Removes the task from the list

    +

    Button displayed next to tasks which the user is can edit, used to delete a task from the list

    @@ -573,7 +589,7 @@
    -

    Opens edit mode for the task

    +

    Button displayed next to tasks which the user is can edit, used to start editing a task

    @@ -593,14 +609,122 @@
    - # - task_list + # + add_task_base
    -

    Registers the task list

    +

    Set of three elements which make up each row of the task table

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_label +
    +
    +
    +
    + +

    Default state for a task, contains only a label with the task message

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_editing +
    +
    +
    +
    + +

    Editing state for a task, contrins a text field and the two edit buttons

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_list_container +
    +
    +
    +
    + +

    Main task list container for the left flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_list_toggle +
    +
    +
    +
    + +

    Button on the top flow used to toggle the task list container

    @@ -632,7 +756,7 @@ generated by LDoc
    diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index a4647a51..18297a4b 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -837,7 +837,7 @@ generated by LDoc diff --git a/docs/index.html b/docs/index.html index cd8ed91c..a5e3d006 100644 --- a/docs/index.html +++ b/docs/index.html @@ -511,7 +511,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index 2b73d7da..6cca966d 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -351,7 +351,7 @@ generated by LDoc diff --git a/docs/modules/utils.alien_evolution_progress.html b/docs/modules/utils.alien_evolution_progress.html index fc152587..6291b757 100644 --- a/docs/modules/utils.alien_evolution_progress.html +++ b/docs/modules/utils.alien_evolution_progress.html @@ -419,7 +419,7 @@ fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on generated by LDoc diff --git a/docs/modules/utils.core.html b/docs/modules/utils.core.html index d3a78a5d..b6393f5d 100644 --- a/docs/modules/utils.core.html +++ b/docs/modules/utils.core.html @@ -1164,7 +1164,7 @@ generated by LDoc diff --git a/docs/modules/utils.debug.html b/docs/modules/utils.debug.html index 661eb841..c5882630 100644 --- a/docs/modules/utils.debug.html +++ b/docs/modules/utils.debug.html @@ -654,7 +654,7 @@ generated by LDoc diff --git a/docs/modules/utils.dump_env.html b/docs/modules/utils.dump_env.html index fff59dbb..2927bed7 100644 --- a/docs/modules/utils.dump_env.html +++ b/docs/modules/utils.dump_env.html @@ -323,7 +323,7 @@ generated by LDoc diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index 663e8dcb..49848f9e 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -1292,7 +1292,7 @@ generated by LDoc diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index 26e97c55..ec13ecfc 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -434,7 +434,7 @@ generated by LDoc diff --git a/docs/modules/utils.math.html b/docs/modules/utils.math.html index c192045d..e4815bc6 100644 --- a/docs/modules/utils.math.html +++ b/docs/modules/utils.math.html @@ -353,7 +353,7 @@ generated by LDoc diff --git a/docs/modules/utils.recipe_locker.html b/docs/modules/utils.recipe_locker.html index 51c8fb76..717e7598 100644 --- a/docs/modules/utils.recipe_locker.html +++ b/docs/modules/utils.recipe_locker.html @@ -441,7 +441,7 @@ generated by LDoc diff --git a/docs/modules/utils.state_machine.html b/docs/modules/utils.state_machine.html index 5708101d..aeb9fd7f 100644 --- a/docs/modules/utils.state_machine.html +++ b/docs/modules/utils.state_machine.html @@ -752,7 +752,7 @@ generated by LDoc diff --git a/docs/modules/utils.table.html b/docs/modules/utils.table.html index 2c9404e6..13f18afb 100644 --- a/docs/modules/utils.table.html +++ b/docs/modules/utils.table.html @@ -1418,7 +1418,7 @@ generated by LDoc diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index f1a4a0be..47a1f7d6 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -651,7 +651,7 @@ generated by LDoc diff --git a/docs/modules/utils.timestamp.html b/docs/modules/utils.timestamp.html index c22b2df7..df8680e8 100644 --- a/docs/modules/utils.timestamp.html +++ b/docs/modules/utils.timestamp.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index 6901e6e6..ffb5dd8e 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -789,7 +789,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index e472eb59..7dba1a3c 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -338,7 +338,7 @@ Please report these errors to [the issues page](issues). generated by LDoc diff --git a/expcore/gui.lua b/expcore/gui.lua index 8e25a7c3..b6237b87 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -5,35 +5,60 @@ @usage-- Defining a button that prints the player's name local example_button = -Gui.new_element{ +Gui.element{ type = 'button', caption = 'Example Button' } -:on_click(function(event) - local player = event.player +:on_click(function(player,element,event) player.print(player.name) end) -@usage-- Defining using a custom function +@usage-- Defining a button with a custom style +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style{ + height = 25, + width = 100 +} +:on_click(function(player,element,event) + player.print(player.name) +end) + +@usage-- Defining a button using a custom function local example_flow_with_button = -Gui.new_element(function(event_trigger,parent) +Gui.element(function(event_trigger,parent) + -- Add the flow the button is in local flow = parent.add{ name = 'example_flow', type = 'flow' } + -- Get the players name + local player = game.players[parent.player_index] + local player_name = player.name + + -- Add the button local element = flow.add{ name = event_trigger, type = 'button', - caption = 'Example Button' + caption = 'Example Button: '..player_name } + -- Set the style of the button + local style = element.style + style.height = 25 + style.width = 100] + style.font_color = player.color + + -- Return the element return element end) -:on_click(function(event) - local player = event.player +:on_click(function(player,element,event) player.print(player.name) end) @@ -62,14 +87,16 @@ local Gui = { --- An index used for debuging to find the file where different elements where registered -- @table file_paths file_paths = {}, - --- The element prototype which is returned from Gui.new_element + --- The element prototype which is returned from Gui.element -- @table _prototype_element _prototype_element = {}, --- The prototype metatable applied to new element defines -- @table _mt_element _mt_element = { __call = function(self,parent,...) - return self._draw(self.name,parent,...) + local element = self._draw(self.name,parent,...) + if self._style then self._style(element.style,element,...) end + return element end } } @@ -85,20 +112,22 @@ Gui._mt_element.__index = Gui._prototype_element @usage-- Defining an element with a table local example_button = -Gui.new_element{ +Gui.element{ type = 'button', caption = 'Example Button' } @usage-- Defining an element with a function local example_flow_with_button = -Gui.new_element(function(event_trigger,parent) +Gui.element(function(event_trigger,parent,...) + -- Add the flow the button is in local flow = parent.add{ name = 'example_flow', type = 'flow' } + -- Add the button local element = flow.add{ name = event_trigger, @@ -106,11 +135,17 @@ Gui.new_element(function(event_trigger,parent) caption = 'Example Button' } + -- Set the style of the button + local style = element.style + style.height = 25 + style.width = 100 + + -- Return the element return element end) ]] -function Gui.new_element(element_define) +function Gui.element(element_define) -- Set the metatable to allow access to register events local element = setmetatable({}, Gui._mt_element) @@ -139,8 +174,54 @@ function Gui.new_element(element_define) return element end +--[[-- Extension of Gui.element when using the table method, values applied after the element is drawn +@tparam ?table|function style_define used to define how the style is applied, using a table is the simplist way of doing this +@treturn table the new element define that is used to register events to this element + +@usage-- Setting the height and width of the example button +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style{ + height = 25, + width = 100 +} + +@usage-- Using a function to set the style +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style(function(style,element,...) + local player = game.players[element.player_index] + style.height = 25 + style.width = 100 + style.font_color = player.color +end) + +]] +function Gui._prototype_element:style(style_define) + -- Add the defination function + if type(style_define) == 'table' then + self._style = function(style) + for key,value in pairs(style_define) do + style[key] = value + end + end + else + self._style = style_define + end + + -- Return the element so event handers can be accessed + return self +end + --[[-- Adds an element to be drawn to the top flow when a player joins @tparam[opt] function authenticator called during toggle or update to decide if the element should be visible +@treturn table the new element define that is used to register events to this element @usage-- Adding the example button example_button:add_to_top_flow(function(player) @@ -151,10 +232,12 @@ end) ]] function Gui._prototype_element:add_to_top_flow(authenticator) Gui.top_elements[self.name] = authenticator or true + return self end --[[-- Adds an element to be drawn to the left flow when a player joins @tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible +@treturn table the new element define that is used to register events to this element @usage-- Adding the example button example_flow_with_button:add_to_left_flow(true) @@ -162,6 +245,7 @@ example_flow_with_button:add_to_left_flow(true) ]] function Gui._prototype_element:add_to_left_flow(open_on_join) Gui.left_elements[self.name] = open_on_join or false + return self end -- This function is called for event event @@ -186,7 +270,7 @@ local function general_event_handler(event) end event.player = player - local success, err = pcall(handler,event) + local success, err = pcall(handler,player,element,event) if not success then error('There as been an error with an event handler for a gui element:\n\t'..err) end @@ -259,31 +343,23 @@ Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.o --- Button which toggles the top flow elements -- @element toggle_top_flow local toggle_top_flow = -Gui.new_element(function(event_trigger,parent) - -- Draw the element - local element = - parent.add{ - name = event_trigger, - type = 'button', - style = mod_gui.button_style, - caption = '<', - tooltip = {'gui_util.button_tooltip'} - } - - -- Change its style - local style = element.style - style.width = 18 - style.height = 36 - style.padding = 0 - style.font = 'default-small-bold' - - -- Return the element - return element -end) -:on_click(function(event) - Gui.toggle_top_flow(event.player) +Gui.element{ + type = 'button', + style = 'back_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + width = 18, + height = 36 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) end) +--- The style that should be used for buttons on the top flow +-- @field Gui.top_flow_button_style +Gui.top_flow_button_style = mod_gui.button_style + --[[-- Gets the flow which contains the elements for the top flow @function Gui.get_top_flow(player) @tparam LuaPlayer player the player that you want to get the flow for @@ -305,7 +381,7 @@ Gui.update_top_flow(game.player) function Gui.update_top_flow(player) local top_flow = Gui.get_top_flow(player) local toggle_button = top_flow[toggle_top_flow.name] - local is_visible = toggle_button.caption == '<' + local is_visible = toggle_button.style.name == 'back_button' -- Set the visible state of all elements in the flow for name,authenticator in pairs(Gui.top_elements) do @@ -335,7 +411,7 @@ Gui.toggle_top_flow(game.player,true) function Gui.toggle_top_flow(player,state) local top_flow = Gui.get_top_flow(player) local toggle_button = top_flow[toggle_top_flow.name] - local new_state = state or toggle_button.caption == '>' + local new_state = state or toggle_button.style.name == 'forward_button' -- Set the visible state of all elements in the flow for name,authenticator in pairs(Gui.top_elements) do @@ -344,11 +420,15 @@ function Gui.toggle_top_flow(player,state) -- Change the style of the toggle button if new_state then - toggle_button.caption = '<' - toggle_button.style.height = 34 + toggle_button.style = 'back_button' + local style = toggle_button.style + style.height = 36 + style.width = 18 else - toggle_button.caption = '>' - toggle_button.style.height = 24 + toggle_button.style = 'forward_button' + local style = toggle_button.style + style.height = 20 + style.width = 18 end return new_state @@ -360,29 +440,17 @@ end --- Button which hides the elements in the left flow -- @element hide_left_flow local hide_left_flow = -Gui.new_element(function(event_trigger,parent) - -- Draw the element - local element = - parent.add{ - name = event_trigger, - type = 'button', - style = mod_gui.button_style, - caption = '<', - tooltip = {'expcore-gui.left-button-tooltip'} - } - - -- Change its style - local style = element.style - style.width = 18 - style.height = 36 - style.padding = 0 - style.font = 'default-small-bold' - - -- Return the element - return element -end) -:on_click(function(event) - Gui.hide_left_flow(event.player) +Gui.element{ + type = 'button', + style = 'back_button', + tooltip = {'expcore-gui.left-button-tooltip'} +} +:style{ + width = 18, + height = 36 +} +:on_click(function(player,_,_) + Gui.hide_left_flow(player) end) --[[-- Gets the flow which contains the elements for the left flow @@ -486,4 +554,195 @@ Event.add(defines.events.on_player_joined_game,function(event) hide_left.visible = show_hide_left end) +--- Helper Functions. +-- @section helperFunctions + +--[[-- Get the player that owns a gui element +@tparam LuaGuiElement element the element that you want to get the owner of +@treturn LuaPlayer the player that owns this element + +@usage-- Geting the owner of an element +local player = Gui.get_player_from_element(element) + +]] +function Gui.get_player_from_element(element) + if not element or not element.valid then return end + return game.players[element.player_index] +end + +--[[-- Will toggle the enabled state of an element or set it to the one given +@tparam LuaGuiElement element the element that you want to toggle the state of +@tparam[opt] boolean state the state that you want to set +@treturn boolean the new enabled state that the element has + +@usage-- Toggling the the enabled state +local new_enabled_state = Gui.toggle_enabled_state(element) + +]] +function Gui.toggle_enabled_state(element,state) + if not element or not element.valid then return end + local new_state = state or not element.enabled + element.enabled = new_state + return new_state +end + +--[[-- Will toggle the visible state of an element or set it to the one given +@tparam LuaGuiElement element the element that you want to toggle the state of +@tparam[opt] boolean state the state that you want to set +@treturn boolean the new visible state that the element has + +@usage-- Toggling the the visible state +local new_visible_state = Gui.toggle_visible_state(element) + +]] +function Gui.toggle_visible_state(element,state) + if not element or not element.valid then return end + local new_state = state or not element.visible + element.visible = new_state + return new_state +end + +--[[-- Destory a gui element without causing any errors, likly if the element may have already been removed +@tparam LuaGuiElement element the element that you want to remove +@treturn boolean true if the element was valid and has been removed + +@usage-- Likely use case for element not existing +Gui.destroy_if_valid(element[child_name]) + +]] +function Gui.destroy_if_valid(element) + if not element or not element.valid then return false end + element.destroy() + return true +end + +--[[-- Draw a flow that has custom element alignments, default is right align +@tparam LuaGuiElement parent the parent element that the alignment flow will be added to +@tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow +@tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow +@tparam[opt='alignment'] string name the name of the alignment flow +@treturn LuaGuiElement the alignment flow that was created + +@usage-- Adding a right align flow +local alignment = Gui.alignment(element,'example_right_alignment') + +@usage-- Adding a horizontal center and top align flow +local alignment = Gui.alignment(element,'example_center_top_alignment','center','top') + +]] +function Gui.alignment(parent,horizontal_align,vertical_align,name) + -- Draw the alignment flow + local alignment = + parent.add{ + name = name or 'alignment', + type = 'flow', + } + + -- Change its style + local style = alignment.style + style.padding = {1,2} + style.vertical_align = vertical_align or 'center' + style.horizontal_align = horizontal_align or 'right' + style.vertically_stretchable = style.vertical_align ~= 'center' + style.horizontally_stretchable = style.horizontal_align ~= 'center' + + -- Return the flow + return alignment +end + +--[[-- Draw a scroll pane that has a table inside of it +@tparam LuaGuiElement parent the parent element that the scroll table will be added to +@tparam number height the maximum height for the scroll pane +@tparam number column_count the number of columns that the table will have +@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called 'table' +@treturn LuaGuiElement the table that was created + +@usage-- Adding a scroll table with max height of 200 and column count of 3 +local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) + +]] +function Gui.scroll_table(parent,height,column_count,name) + -- Draw the scroll + local scroll = + parent.add{ + name = name or 'scroll', + type = 'scroll-pane', + direction = 'vertical', + horizontal_scroll_policy = 'never', + vertical_scroll_policy = 'auto-and-reserve-space', + style = 'scroll_pane_under_subheader' + } + + -- Change the style of the scroll + local scroll_style = scroll.style + scroll_style.padding = {1,2} + scroll_style.maximal_height = height + scroll_style.horizontally_stretchable = true + + -- Draw the table + local scroll_table = + scroll.add{ + type = 'table', + name = 'table', + column_count = column_count + } + + -- Change the style of the table + local table_style = scroll_table.style + table_style.padding = 0 + table_style.cell_padding = 0 + table_style.vertical_align = 'center' + table_style.horizontally_stretchable = true + + -- Return the scroll table + return scroll_table +end + +--[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons +@tparam LuaGuiElement parent the parent element that the header will be added to +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons +@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' +@treturn LuaGuiElement either the header or the header alignment if add_alignment is true + +@usage-- Adding a custom header +local header_alignment = Gui.header( + element, + 'example_header', + 'Example Caption', + 'Example Tooltip', + true +) + +]] +function Gui.header(parent,caption,tooltip,add_alignment,name) + -- Draw the header + local header = + parent.add{ + name = name or 'header', + type = 'frame', + style = 'subheader_frame' + } + + -- Change the style of the header + local style = header.style + style.padding = {2,4} + style.use_header_filler = false + style.horizontally_stretchable = true + + -- Draw the caption label + header.add{ + name = 'header_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + + -- Return either the header or the added alignment + return add_alignment and Gui.alignment(header) or header +end + +-- Module return return Gui \ No newline at end of file diff --git a/expcore/store.lua b/expcore/store.lua index f58e41b9..735ccef4 100644 --- a/expcore/store.lua +++ b/expcore/store.lua @@ -27,7 +27,7 @@ local player_scores = Store.register(function(player) -- Use player name as the end) -- When any key in the store is changed this function will trigger -Store.watch(player_scores,function(value,key) +Store.watch(player_scores,function(value,key,old_value) game.print(key..' now has a score of '..value) end) @@ -175,7 +175,7 @@ local player_scores = Store.register(function(player) end) -- Register the watcher so that when we change the value the message is printed -Store.watch(player_scores,function(value,key) +Store.watch(player_scores,function(value,key,old_value) game.print(key..' now has a score of '..value) end) @@ -274,18 +274,21 @@ Store.clear(player_scores) ]] function Store.clear(store,key) key = Store.validate(store,key,2) + local old_value -- Check if there is a key being used if key then if type(data_store[store]) == 'table' then + old_value = data_store[store][key] data_store[store][key] = nil end else + old_value = data_store[store] data_store[store] = nil end -- Trigger any watch functions - Store.raw_trigger(store,key,nil) + Store.raw_trigger(store,key,nil,old_value) end --[[-- Used to set the data in a store, will trigger any watchers, key is optional depending on if you are using them @@ -325,19 +328,22 @@ function Store.set(store,key,value) -- Check the store is valid key = Store.validate(store,key,2) + local old_value -- If there is a key being used then the store must be a able if key then if type(data_store[store]) ~= 'table' then data_store[store] = {_value = data_store[store]} end + old_value = data_store[store][key] data_store[store][key] = value else + old_value = data_store[store] data_store[store] = value end -- Trigger any watchers - Store.raw_trigger(store,key,value) + Store.raw_trigger(store,key,value,old_value) end --[[-- Used to update the data in a store, use this with tables, will trigger any watchers, key is optional depending on if you are using them @@ -386,7 +392,7 @@ function Store.update(store,key,updater) -- Check the store is valid key = Store.validate(store,key,2) - local value + local value, old_value -- If a key is used then the store must be a table if key then @@ -397,6 +403,7 @@ function Store.update(store,key,updater) -- Call the updater and if it returns a value then set this value local rtn = updater(data_store[store][key]) if rtn then + old_value = data_store[store][key] data_store[store][key] = rtn end value = data_store[store][key] @@ -405,6 +412,7 @@ function Store.update(store,key,updater) -- Call the updater and if it returns a value then set this value local rtn = updater(data_store[store]) if rtn then + old_value = data_store[store][key] data_store[store] = rtn end value = data_store[store] @@ -412,7 +420,7 @@ function Store.update(store,key,updater) end -- Trigger any watchers - Store.raw_trigger(store,key,value) + Store.raw_trigger(store,key,value,old_value) end --[[-- Used to update all values that are in a store, similar to Store.update but acts on all keys at once, will trigger watchers for every key present @@ -455,7 +463,7 @@ function Store.map(store,updater) if rtn then data[key] = rtn end - Store.raw_trigger(store,key,data[key]) + Store.raw_trigger(store,key,data[key],value) end end @@ -476,9 +484,10 @@ function Store.trigger(store,key) -- Get the data from the data store local data = data_store[store] if key then - Store.raw_trigger(store,key,data[key]) + data = data[key] + Store.raw_trigger(store,key,data,data) else - Store.raw_trigger(store,key,data) + Store.raw_trigger(store,key,data,data) end end @@ -486,6 +495,7 @@ end @tparam number store the uid of the store that you want to trigger @tparam[opt] ?string|any key the key that you want to trigger, must be a string unless you have a serializer @tparam[opt] any value the new value that is at this key or store, passed directly to the watcher +@tparam[opt] any old_value the old value that was at this key or store often the same if value is a table, passed directly to the watcher @usage-- Triggering a manule call of the watchers -- The type of store we use does not really matter for this as long as you pass it what you watchers are expecting @@ -493,16 +503,16 @@ local scenario_diffculty = Store.register() -- Trigger the watchers with a fake change of diffculty -- This is mostly used internally but it can be useful in other cases -Store.raw_trigger(scenario_diffculty,nil,'normal') +Store.raw_trigger(scenario_diffculty,nil,'normal','normal') ]] -function Store.raw_trigger(store,key,value) +function Store.raw_trigger(store,key,value,old_value) key = Store.validate(store,key,2) -- Get the watchers and then loop over them local watchers = Store.watchers[store] or {} for _,watcher in pairs(watchers) do - local success, err = pcall(watcher,value,key) + local success, err = pcall(watcher,value,key,old_value) if not success then error('Store watcher casued an error:\n\t'..err) end diff --git a/modules/control/tasks.lua b/modules/control/tasks.lua index 6b2d9630..0806efde 100644 --- a/modules/control/tasks.lua +++ b/modules/control/tasks.lua @@ -89,8 +89,8 @@ Tasks.remove_task(task_id) function Tasks.remove_task(task_id) local task = Store.get(task_store,task_id) local force_name = task.force_name - Store.clear(task_store,task_id) table.remove_element(force_tasks[force_name],task_id) + Store.clear(task_store,task_id) end --[[-- Update the message and last edited information for a task diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index d82a3a77..9f393205 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -12,337 +12,455 @@ local format_time,table_keys = ext_require('expcore.common','format_time','table local Tasks = require 'modules.control.tasks' --- @dep modules.control.tasks --- If a player is allowed to use the edit buttons -local function player_allowed_edit(player,task) +local function check_player_permissions(player,task) if task then + -- When a task is given check if the player can edit it + local allow_edit_task = config.allow_edit_task + + -- Check if the player being the last to edit will override existing permisisons if config.user_can_edit_own_tasks and task.last_edit_name == player.name then return true end - else - if config.any_user_can_add_new_task then + + -- Check player has permisison based on value in the config + if allow_edit_task == 'all' then return true + elseif allow_edit_task == 'admin' then + return player.admin + elseif allow_edit_task == 'expcore.roles' then + return Roles.player_allowed(player,config.edit_tasks_role_permission) end - end - if config.only_admins_can_edit and not player.admin then + -- Return false as all other condidtions have not been met + return false + else + -- When a task is not given check if the player can add a new task + local allow_add_task = config.allow_add_task + + -- Check player has permisison based on value in the config + if allow_add_task == 'all' then + return true + elseif allow_add_task == 'admin' then + return player.admin + elseif allow_add_task == 'expcore.roles' then + return Roles.player_allowed(player,config.expcore_roles_add_permission) + end + + -- Return false as all other condidtions have not been met return false end - - if config.edit_tasks_role_permission and not Roles.player_allowed(player,config.edit_tasks_role_permission) then - return false - end - - return true end ---- Button in the header to add a new task +--- Button displayed in the ehader bar, used to add a new task -- @element add_new_task local add_new_task = -Gui.new_button() -:set_sprites('utility/add') -:set_tooltip{'task-list.add-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/add', + tooltip = {'task-list.add-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,_,_) Tasks.add_task(player.force.name,nil,player.name) end) ---- Used to save changes to a task +--- Button displayed next to tasks which the user is currently editing, used to save changes -- @element confirm_edit local confirm_edit = -Gui.new_button() -:set_sprites('utility/downloaded') -:set_tooltip{'task-list.confirm-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/downloaded', + tooltip = {'task-list.confirm-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element,_) local task_id = element.parent.name - local new_message = element.parent.task.text + local new_message = element.parent.task_entry.text Tasks.set_editing(task_id,player.name) Tasks.update_task(task_id,new_message,player.name) end) ---- Used to cancel any changes you made to a task +--- Button displayed next to tasks which the user is currently editing, used to discard changes -- @element cancel_edit local cancel_edit = -Gui.new_button() -:set_sprites('utility/close_black') -:set_tooltip{'task-list.cancel-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + tooltip = {'task-list.cancel-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element,_) local task_id = element.parent.name Tasks.set_editing(task_id,player.name) end) ---- Removes the task from the list +--- Button displayed next to tasks which the user is can edit, used to delete a task from the list -- @element discard_task local discard_task = -Gui.new_button() -:set_sprites('utility/trash') -:set_tooltip{'task-list.discard-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) - local task_id = element.parent.name +Gui.element{ + type = 'sprite-button', + sprite = 'utility/trash', + tooltip = {'task-list.discard-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(_,element,_) + local task_id = element.parent.name:sub(6) Tasks.remove_task(task_id) end) ---- Opens edit mode for the task +--- Button displayed next to tasks which the user is can edit, used to start editing a task -- @element edit_task local edit_task = -Gui.new_button() -:set_sprites('utility/rename_icon_normal') -:set_tooltip{'task-list.edit-tooltip-none'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) - local task_id = element.parent.name +Gui.element{ + type = 'sprite-button', + sprite = 'utility/rename_icon_normal', + tooltip = {'task-list.edit-tooltip-none'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element,_) + local task_id = element.parent.name:sub(6) Tasks.set_editing(task_id,player.name,true) end) ---[[ Generates each task, handles both view and edit mode - element - > count-"task_id" - >> label - > "task_id" - >> task - >> cancel_edit (edit mode) - >> confirm_edit (edit mode) - > edit-"task_id" - >> edit_task - >> discard_task -]] -local function generate_task(player,element,task_id) +--- Set of three elements which make up each row of the task table +-- @element add_task_base +local add_task_base = +Gui.element(function(_,parent,task_id) + -- Add the task number label + parent.add{ + name = 'count-'..task_id, + type = 'label', + caption = '0)' + } + + -- Add a flow which will contain the task message and edit buttons + local task_flow = + parent.add{ + name = task_id, + type = 'flow', + } + + -- Set the padding on the task flow + local task_flow_style = task_flow.style + task_flow_style.padding = 0 + + -- Add the two edit buttons outside the task flow + local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..task_id) + edit_task(edit_flow) + discard_task(edit_flow) + + -- Return the task flow as the main element + return task_flow +end) + +-- Removes the three elements that are added as part of the task base +local function remove_task_base(parent,task_id) + Gui.destroy_if_valid(parent['count-'..task_id]) + Gui.destroy_if_valid(parent['edit-'..task_id]) + Gui.destroy_if_valid(parent[task_id]) +end + +--- Default state for a task, contains only a label with the task message +-- @element task_label +local task_label = +Gui.element(function(_,parent,task) + local message = task.message + local last_edit_name = task.last_edit_name + local last_edit_time = task.last_edit_time + + -- Draw the element + local element = + parent.add{ + name = 'task_entry', + type = 'label', + caption = message, + tooltip = {'task-list.last-edit', last_edit_name, format_time(last_edit_time)} + } + + -- Change the style + local style = element.style + style.single_line = false + style.maximal_width = 150 + + -- Return the element + return element +end) + +--- Editing state for a task, contrins a text field and the two edit buttons +-- @element task_editing +local task_editing = +Gui.element(function(_,parent,task) + local message = task.message + + -- Draw the element + local element = + parent.add{ + name = 'task_entry', + type = 'textfield', + text = message + } + + -- Change the style + local style = element.style + style.maximal_width = 150 + style.height = 20 + + -- Add the edit buttons + cancel_edit(parent) + confirm_edit(parent) + + -- Return the element + return element +end) + +--- Updates a task for a player +local function update_task(player,task_table,task_id) local task = Tasks.get_task(task_id) local task_ids = Tasks.get_force_task_ids(player.force.name) local task_number = table.index_of(task_ids, task_id) + -- Task no longer exists so should be removed from the list if not task then - -- task is nil so remove it from the list - element.parent.no_tasks.visible = #task_ids == 1 - Gui.destroy_if_valid(element['count-'..task_id]) - Gui.destroy_if_valid(element['edit-'..task_id]) - Gui.destroy_if_valid(element[task_id]) - - else - local message = task.message - local editing = task.curently_editing[player.name] - local last_edit_name = task.last_edit_name - local last_edit_time = task.last_edit_time - - element.parent.no_tasks.visible = false - -- if it is not already present then add it now - local task_area = element[task_id] - if not task_area then - -- label to show the task number - element.add{ - name='count-'..task_id, - type='label', - caption=task_number..')' - } - - -- area which stores the task and buttons - task_area = - element.add{ - name=task_id, - type='flow', - } - Gui.set_padding(task_area) - - -- if the player can edit then it adds the edit and delete button - local flow = Gui.create_alignment(element,'edit-'..task_id) - local sub_flow = flow.add{type='flow',name=task_id} - - edit_task(sub_flow) - discard_task(sub_flow) - - end - - -- update the number indexes and the current editing players - element['count-'..task_id].caption = task_number..')' - - local edit_area = element['edit-'..task_id][task_id] - local players = table_keys(task.editing) - local allowed = player_allowed_edit(player,task) - - edit_area.visible = allowed - - if #players > 0 then - edit_area[edit_task.name].tooltip = {'task-list.edit-tooltip',table.concat(players,', ')} - else - edit_area[edit_task.name].tooltip = {'task-list.edit-tooltip-none'} - end - - -- draws/updates the task area - local element_type = task_area.task and task_area.task.type or nil - if not editing and element_type == 'label' then - -- update the label already present - task_area.task.caption = message - task_area.task.tooltip = {'task-list.last-edit',last_edit_name,format_time(last_edit_time)} - - elseif not editing then - -- create the label, view mode - if edit_area then - edit_area[edit_task.name].enabled = true - end - - task_area.clear() - - local label = - task_area.add{ - name='task', - type='label', - caption=message, - tooltip={'task-list.last-edit',last_edit_name,format_time(last_edit_time)} - } - label.style.single_line = false - label.style.maximal_width = 150 - - elseif editing and element_type ~= 'textfield' then - -- create the text field, edit mode, update it omitted as value is being edited - if edit_area then - edit_area[edit_task.name].enabled = false - end - - task_area.clear() - - local entry = - task_area.add{ - name='task', - type='textfield', - text=message - } - entry.style.maximal_width = 150 - entry.style.height = 20 - - cancel_edit(task_area) - confirm_edit(task_area) - - end - + task_table.parent.no_tasks.visible = #task_ids == 0 + remove_task_base(task_table,task_id) + return end + -- Get the task flow for this task + local task_flow = task_table[task_id] or add_task_base(task_table,task_id) + task_table.parent.no_tasks.visible = false + task_table['count-'..task_id].caption = task_number..')' + + -- Update the edit flow + local edit_flow = task_table['edit-'..task_id] + local player_allowed_edit = check_player_permissions(player,task) + local players_editing = table_keys(task.curently_editing) + local edit_task_element = edit_flow[edit_task.name] + local discard_task_element = edit_flow[discard_task.name] + + edit_task_element.visible = player_allowed_edit + discard_task_element.visible = player_allowed_edit + if #players_editing > 0 then + edit_task_element.tooltip = {'task-list.edit-tooltip',table.concat(players_editing,', ')} + else + edit_task_element.tooltip = {'task-list.edit-tooltip-none'} + end + + -- Check if the player is was editing and/or currently editing + local task_entry = task_flow.task_entry or task_label(task_flow,task) + local player_was_editing = task_entry.type == 'textfield' + local player_is_editing = task.curently_editing[player.name] + + -- Update the task flow + if not player_was_editing and not player_is_editing then + -- Update the task message label + local message = task.message + local last_edit_name = task.last_edit_name + local last_edit_time = task.last_edit_time + task_entry.caption = message + task_entry.tooltip = {'task-list.last-edit', last_edit_name, format_time(last_edit_time)} + + elseif player_was_editing and not player_is_editing then + -- Player was editing but is no longer, remove text field and add label + edit_task_element.enabled = true + task_flow.clear() + task_label(task_flow,task) + + elseif not player_was_editing and player_is_editing then + -- Player was not editing but now is, remove label and add text field + edit_task_element.enabled = false + task_flow.clear() + task_editing(task_flow,task) + + end end ---[[ generates the main gui structure - element - > container - >> header - >>> right aligned add_new_task - >> scroll - >>> no_tasks - >>> table -]] -local function generate_container(player,element) - Gui.set_padding(element,2,2,2,2) - element.style.minimal_width = 200 +local function update_all_tasks(player,scroll_table) + local task_ids = Tasks.get_force_task_ids(player.force.name) + if #task_ids > 0 then + for _,task_id in ipairs(task_ids) do + update_task(player,scroll_table,task_id) + end + end +end - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' +--- Main task list container for the left flow +-- @element task_list_container +local task_list_container = +Gui.element(function(event_trigger,parent) + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' } - Gui.set_padding(container) - container.style.vertically_stretchable = false - -- main header for the gui - local header_area = Gui.create_header( + -- Set the frame style + frame.style.padding = 2 + + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } + + -- Set the container style + local style = container.style + style.vertically_stretchable = false + + -- Draw the header + local header = Gui.header( container, {'task-list.main-caption'}, {'task-list.sub-tooltip'}, true ) - --- Right aligned button to toggle the section - if player_allowed_edit(player) then - add_new_task(header_area) - end + -- Draw the new task button + local player = Gui.get_player_from_element(parent) + local add_new_task_element = add_new_task(header) + add_new_task_element.visible = check_player_permissions(player) - -- table that stores all the data - local flow_table = Gui.create_scroll_table(container,3,185) - flow_table.draw_horizontal_lines = true - flow_table.vertical_centering = false - flow_table.style.top_cell_padding = 3 - flow_table.style.bottom_cell_padding = 3 + -- Draw the scroll table for the tasks + local scroll_table = Gui.scroll_table(container,185,3) + scroll_table.draw_horizontal_lines = true + scroll_table.vertical_centering = false - -- message to say that you have no tasks - local non_made = - flow_table.parent.add{ - name='no_tasks', - type='label', - caption={'task-list.no-tasks'} + -- Change the style of the scroll table + local scroll_table_style = scroll_table.style + scroll_table_style.top_cell_padding = 3 + scroll_table_style.bottom_cell_padding = 3 + + -- Draw the no tasks label + local no_tasks_label = + scroll_table.parent.add{ + name = 'no_tasks', + type = 'label', + caption = {'task-list.no-tasks'} } - non_made.style.width = 200 - non_made.style.single_line = false - return flow_table -end + -- Change the style of the no tasks label + local no_tasks_style = no_tasks_label.style + no_tasks_style.padding = {2,4} + no_tasks_style.single_line = false + no_tasks_style.width = 200 ---- Registers the task list --- @element task_list -local task_list = -Gui.new_left_frame('gui/task-list') -:set_sprites('utility/not_enough_repair_packs_icon') -:set_direction('vertical') -:set_tooltip{'task-list.main-tooltip'} -:set_open_by_default() -:on_creation(function(player,element) - local data_table = generate_container(player,element) + -- Add any existing tasks local task_ids = Tasks.get_force_task_ids(player.force.name) - - for _,task_id in pairs(task_ids) do - generate_task(player,data_table,task_id) + if #task_ids > 0 then + no_tasks_style.visible = false + for _,task_id in ipairs(task_ids) do + update_task(player,scroll_table,task_id) + end end + + -- Return the exteral container + return frame end) -:on_update(function(player,element) - local data_table = element.container.scroll.table +:add_to_left_flow(function(player) local task_ids = Tasks.get_force_task_ids(player.force.name) + return #task_ids > 0 +end) - for _,task_id in pairs(task_ids) do - generate_task(player,data_table,task_id) - end +--- Button on the top flow used to toggle the task list container +-- @element task_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'utility/not_enough_repair_packs_icon', + tooltip = {'task-list.main-tooltip'}, + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/task-list') +end) +:on_click(function(player,_,_) + Gui.toggle_left_element(player, task_list_container) end) --- When a new task is added it will udpate the task list for everyone on that force -Tasks.on_update(function(task,task_id) - local players +Tasks.on_update(function(task,task_id,removed_task) + -- Get the force to update, task is nil when removed + local force if task then - local force = game.forces[task.force_name] - players = force.connected_players + force = game.forces[task.force_name] else - players = game.connected_players + force = game.forces[removed_task.force_name] end - for _,player in pairs(players) do - local frame = task_list:get_frame(player) - local element = frame.container.scroll.table - generate_task(player,element,task_id) + -- Update the task for all the players on the force + local task_ids = Tasks.get_force_task_ids(force.name) + for _,player in pairs(force.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[task_list_container.name] + local scroll_table = frame.container.scroll.table + + -- Update the task that was changed + update_task(player,scroll_table,task_id) + + -- Update the numbering of the other tasks if the task was removed + if not task then + for task_number, next_task_id in pairs(task_ids) do + scroll_table['count-'..next_task_id].caption = task_number..')' + end + end end + end) --- Update the tasks when the player joins -Event.add(defines.events.on_player_joined_game,task_list 'redraw') +Event.add(defines.events.on_player_joined_game,function(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[task_list_container.name] + local scroll_table = frame.container.scroll.table + update_all_tasks(player,scroll_table) +end) --- Makes sure the right buttons are present when roles change -Event.add(Roles.events.on_role_assigned,task_list 'redraw') -Event.add(Roles.events.on_role_unassigned,task_list 'redraw') +local function role_update_event(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local container = left_flow[task_list_container.name].container -return task_list \ No newline at end of file + -- Update the tasks, incase the user can now edit them + local scroll_table = container.scroll.table + update_all_tasks(player,scroll_table) + + -- Update the new task button incase the user can now add them + local add_new_task_element = container.header.alignment[add_new_task.name] + add_new_task_element.visible = check_player_permissions(player) +end + +Event.add(Roles.events.on_role_assigned,role_update_event) +Event.add(Roles.events.on_role_unassigned,role_update_event) \ No newline at end of file From b74c3349130005fd1d73012fecb0a7347083d044 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 24 Oct 2019 17:23:44 +0100 Subject: [PATCH 05/81] Few Edits to task list --- expcore/gui.lua | 4 +- modules/gui/task-list.lua | 166 ++++++++++++++++++++------------------ 2 files changed, 91 insertions(+), 79 deletions(-) diff --git a/expcore/gui.lua b/expcore/gui.lua index b6237b87..96193316 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -669,13 +669,13 @@ function Gui.scroll_table(parent,height,column_count,name) type = 'scroll-pane', direction = 'vertical', horizontal_scroll_policy = 'never', - vertical_scroll_policy = 'auto-and-reserve-space', + vertical_scroll_policy = 'auto', style = 'scroll_pane_under_subheader' } -- Change the style of the scroll local scroll_style = scroll.style - scroll_style.padding = {1,2} + scroll_style.padding = {1,3} scroll_style.maximal_height = height scroll_style.horizontally_stretchable = true diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index 9f393205..c36c3422 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -69,13 +69,13 @@ Gui.element{ Tasks.add_task(player.force.name,nil,player.name) end) ---- Button displayed next to tasks which the user is currently editing, used to save changes --- @element confirm_edit -local confirm_edit = +--- Button displayed next to tasks which the user is can edit, used to start editing a task +-- @element edit_task +local edit_task = Gui.element{ type = 'sprite-button', - sprite = 'utility/downloaded', - tooltip = {'task-list.confirm-tooltip'}, + sprite = 'utility/rename_icon_normal', + tooltip = {'task-list.edit-tooltip-none'}, style = 'tool_button' } :style{ @@ -84,29 +84,8 @@ Gui.element{ width = 20 } :on_click(function(player,element,_) - local task_id = element.parent.name - local new_message = element.parent.task_entry.text - Tasks.set_editing(task_id,player.name) - Tasks.update_task(task_id,new_message,player.name) -end) - ---- Button displayed next to tasks which the user is currently editing, used to discard changes --- @element cancel_edit -local cancel_edit = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/close_black', - tooltip = {'task-list.cancel-tooltip'}, - style = 'tool_button' -} -:style{ - padding = -2, - height = 20, - width = 20 -} -:on_click(function(player,element,_) - local task_id = element.parent.name - Tasks.set_editing(task_id,player.name) + local task_id = element.parent.name:sub(6) + Tasks.set_editing(task_id,player.name,true) end) --- Button displayed next to tasks which the user is can edit, used to delete a task from the list @@ -128,25 +107,6 @@ Gui.element{ Tasks.remove_task(task_id) end) ---- Button displayed next to tasks which the user is can edit, used to start editing a task --- @element edit_task -local edit_task = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/rename_icon_normal', - tooltip = {'task-list.edit-tooltip-none'}, - style = 'tool_button' -} -:style{ - padding = -2, - height = 20, - width = 20 -} -:on_click(function(player,element,_) - local task_id = element.parent.name:sub(6) - Tasks.set_editing(task_id,player.name,true) -end) - --- Set of three elements which make up each row of the task table -- @element add_task_base local add_task_base = @@ -185,6 +145,83 @@ local function remove_task_base(parent,task_id) Gui.destroy_if_valid(parent[task_id]) end +--- Button displayed next to tasks which the user is currently editing, used to save changes +-- @element confirm_edit +local task_editing +local confirm_edit = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/downloaded', + tooltip = {'task-list.confirm-tooltip'}, + style = 'shortcut_bar_button_green' +} +:style{ + padding = -2, + right_margin = -3, + height = 22, + width = 22 +} +:on_click(function(player,element,_) + local task_id = element.parent.name + local new_message = element.parent[task_editing.name].text + Tasks.set_editing(task_id,player.name) + Tasks.update_task(task_id,new_message,player.name) +end) + +--- Button displayed next to tasks which the user is currently editing, used to discard changes +-- @element cancel_edit +local cancel_edit = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + tooltip = {'task-list.cancel-tooltip'}, + style = 'shortcut_bar_button_red' +} +:style{ + padding = -2, + right_margin = -3, + height = 22, + width = 22 +} +:on_click(function(player,element,_) + local task_id = element.parent.name + Tasks.set_editing(task_id,player.name) +end) + +--- Editing state for a task, contrins a text field and the two edit buttons +-- @element task_editing +task_editing = +Gui.element(function(event_trigger,parent,task) + local message = task.message + + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'textfield', + text = message, + clear_and_focus_on_right_click = true + } + + -- Change the style + local style = element.style + style.maximal_width = 110 + style.height = 20 + + -- Add the edit buttons + cancel_edit(parent) + confirm_edit(parent) + + -- Return the element + return element +end) +:on_confirmed(function(player,element,_) + local task_id = element.parent.name + local new_message = element.text + Tasks.set_editing(task_id,player.name) + Tasks.update_task(task_id,new_message,player.name) +end) + --- Default state for a task, contains only a label with the task message -- @element task_label local task_label = @@ -196,7 +233,7 @@ Gui.element(function(_,parent,task) -- Draw the element local element = parent.add{ - name = 'task_entry', + name = task_editing.name, type = 'label', caption = message, tooltip = {'task-list.last-edit', last_edit_name, format_time(last_edit_time)} @@ -211,33 +248,6 @@ Gui.element(function(_,parent,task) return element end) ---- Editing state for a task, contrins a text field and the two edit buttons --- @element task_editing -local task_editing = -Gui.element(function(_,parent,task) - local message = task.message - - -- Draw the element - local element = - parent.add{ - name = 'task_entry', - type = 'textfield', - text = message - } - - -- Change the style - local style = element.style - style.maximal_width = 150 - style.height = 20 - - -- Add the edit buttons - cancel_edit(parent) - confirm_edit(parent) - - -- Return the element - return element -end) - --- Updates a task for a player local function update_task(player,task_table,task_id) local task = Tasks.get_task(task_id) @@ -266,13 +276,15 @@ local function update_task(player,task_table,task_id) edit_task_element.visible = player_allowed_edit discard_task_element.visible = player_allowed_edit if #players_editing > 0 then + edit_task_element.hovered_sprite = 'utility/warning_icon' edit_task_element.tooltip = {'task-list.edit-tooltip',table.concat(players_editing,', ')} else + edit_task_element.hovered_sprite = edit_task_element.sprite edit_task_element.tooltip = {'task-list.edit-tooltip-none'} end -- Check if the player is was editing and/or currently editing - local task_entry = task_flow.task_entry or task_label(task_flow,task) + local task_entry = task_flow[task_editing.name] or task_label(task_flow,task) local player_was_editing = task_entry.type == 'textfield' local player_is_editing = task.curently_editing[player.name] @@ -295,7 +307,7 @@ local function update_task(player,task_table,task_id) -- Player was not editing but now is, remove label and add text field edit_task_element.enabled = false task_flow.clear() - task_editing(task_flow,task) + task_editing(task_flow,task).focus() end end From 0b340ab899841cfa187b7d80ab189b8a05fdd9f7 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 24 Oct 2019 21:34:28 +0100 Subject: [PATCH 06/81] Updated Warps List --- config/_file_loader.lua | 2 +- config/roles.lua | 7 +- config/tasks.lua | 9 +- config/warps.lua | 43 +- docs/addons/Advanced-Start.html | 2 +- docs/addons/Chat-Popups.html | 2 +- docs/addons/Chat-Reply.html | 2 +- docs/addons/Compilatron.html | 2 +- docs/addons/Damage-Popups.html | 2 +- docs/addons/Death-Logger.html | 2 +- docs/addons/Discord-Alerts.html | 2 +- docs/addons/Player-Colours.html | 2 +- docs/addons/Pollution-Grading.html | 2 +- docs/addons/Scorched-Earth.html | 2 +- docs/addons/Spawn-Area.html | 2 +- docs/commands/Admin-Chat.html | 2 +- docs/commands/Bonus.html | 2 +- docs/commands/Cheat-Mode.html | 2 +- docs/commands/Clear-Inventory.html | 2 +- docs/commands/Debug.html | 2 +- docs/commands/Find.html | 2 +- docs/commands/Help.html | 2 +- docs/commands/Home.html | 2 +- docs/commands/Interface.html | 2 +- docs/commands/Jail.html | 2 +- docs/commands/Kill.html | 2 +- docs/commands/Me.html | 2 +- docs/commands/Rainbow.html | 2 +- docs/commands/Repair.html | 2 +- docs/commands/Reports.html | 2 +- docs/commands/Roles.html | 2 +- docs/commands/Spawn.html | 2 +- docs/commands/Tag.html | 2 +- docs/commands/Teleport.html | 2 +- docs/commands/Warnings.html | 2 +- docs/configs/Advanced-Start.html | 2 +- docs/configs/Bonuses.html | 2 +- docs/configs/Chat-Reply.html | 2 +- docs/configs/Commands-Auth-Admin.html | 2 +- docs/configs/Commands-Auth-Roles.html | 2 +- .../Commands-Auth-Runtime-Disable.html | 2 +- docs/configs/Commands-Parse-Roles.html | 2 +- docs/configs/Commands-Parse.html | 2 +- docs/configs/Compilatron.html | 2 +- docs/configs/Death-Logger.html | 2 +- docs/configs/Discord-Alerts.html | 2 +- docs/configs/File-Loader.html | 2 +- docs/configs/Permission-Groups.html | 2 +- docs/configs/Player-List.html | 2 +- docs/configs/Pollution-Grading.html | 2 +- docs/configs/Popup-Messages.html | 2 +- docs/configs/Preset-Player-Colours.html | 2 +- docs/configs/Repair.html | 2 +- docs/configs/Rockets.html | 2 +- docs/configs/Roles.html | 2 +- docs/configs/Science.html | 2 +- docs/configs/Scorched-Earth.html | 2 +- docs/configs/Spawn-Area.html | 2 +- docs/configs/Tasks.html | 17 +- docs/configs/Warnings.html | 2 +- docs/configs/Warps.html | 324 +++--- docs/control/Jail.html | 2 +- docs/control/Production.html | 2 +- docs/control/Reports.html | 2 +- docs/control/Rockets.html | 2 +- docs/control/Tasks.html | 2 +- docs/control/Warnings.html | 2 +- docs/control/Warps.html | 2 +- docs/core/Commands.html | 2 +- docs/core/Common-Library.html | 2 +- docs/core/Gui.html | 2 +- docs/core/Permissions-Groups.html | 2 +- docs/core/Roles.html | 2 +- docs/core/Store.html | 2 +- docs/core/Sudo.html | 2 +- docs/guis/Player-List.html | 2 +- docs/guis/Rocket-Info.html | 2 +- docs/guis/Science-Info.html | 2 +- docs/guis/Task-List.html | 198 ++-- docs/guis/Warps-List.html | 446 ++++++--- docs/index.html | 2 +- docs/modules/control.html | 2 +- .../utils.alien_evolution_progress.html | 2 +- docs/modules/utils.core.html | 2 +- docs/modules/utils.debug.html | 2 +- docs/modules/utils.dump_env.html | 2 +- docs/modules/utils.event.html | 2 +- docs/modules/utils.event_core.html | 2 +- docs/modules/utils.math.html | 2 +- docs/modules/utils.recipe_locker.html | 2 +- docs/modules/utils.state_machine.html | 2 +- docs/modules/utils.table.html | 2 +- docs/modules/utils.task.html | 2 +- docs/modules/utils.timestamp.html | 2 +- docs/topics/license.html | 2 +- docs/topics/readme.md.html | 2 +- expcore/gui.lua | 28 +- locale/en/gui.cfg | 2 +- modules/control/warps.lua | 4 +- modules/gui/task-list.lua | 4 +- modules/gui/warp-list.lua | 947 ++++++++++-------- 101 files changed, 1294 insertions(+), 913 deletions(-) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index b7ccbd92..7629b905 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -41,7 +41,7 @@ return { -- GUI --'modules.gui.rocket-info', --'modules.gui.science-info', - --'modules.gui.warp-list', + 'modules.gui.warp-list', 'modules.gui.task-list', --'modules.gui.player-list', --'modules.commands.debug', diff --git a/config/roles.lua b/config/roles.lua index d46d08fe..8bc10b92 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -61,7 +61,8 @@ Roles.new_role('Administrator','Admin') :set_flag('instance-respawn') :set_parent('Moderator') :allow{ - 'gui/warp-list/no-limit', + 'gui/warp-list/bypass-cooldown', + 'gui/warp-list/bypass-proximity', } Roles.new_role('Moderator','Mod') @@ -179,7 +180,9 @@ Roles.new_role('Member','Mem') :set_custom_color{r=24,g=172,b=188} :set_parent('Regular') :allow{ + 'gui/task-list/add', 'gui/task-list/edit', + 'gui/warp-list/add', 'gui/warp-list/edit' } @@ -215,6 +218,8 @@ local default = Roles.new_role('Guest','') 'gui/science-info', 'gui/task-list', 'gui/warp-list', + 'gui/warp-list/apply-cooldown', + 'gui/warp-list/apply-proximity', } --- Jail role diff --git a/config/tasks.lua b/config/tasks.lua index 994acff8..f7968e8e 100644 --- a/config/tasks.lua +++ b/config/tasks.lua @@ -2,11 +2,12 @@ -- @config Tasks return { - -- values can be all, admin, expcore.roles, none + -- Adding tasks allow_add_task = 'all', --- @setting allow_add_task dictates who is allowed to add new tasks; values: all, admin, expcore.roles, none - expcore_roles_add_permission = 'gui/task-list/add', --- @setting expcore_roles_add_permission if expcore.roles is used then this is the required permission - -- values can be all, admin, expcore.roles, none + expcore_roles_allow_add_task = 'gui/task-list/add', --- @setting expcore_roles_allow_add_task if expcore.roles is used then this is the required permission + + -- Editing tasks allow_edit_task = 'expcore.roles', --- @setting allow_edit_task dictates who is allowed to edit existing tasks; values: all, admin, expcore.roles, none - expcore_roles_edit_permission = 'gui/task-list/edit', --- @setting expcore_roles_edit_permission if expcore.roles is used then this is the required permission + expcore_roles_allow_edit_task = 'gui/task-list/edit', --- @setting expcore_roles_allow_edit_task if expcore.roles is used then this is the required permission user_can_edit_own_tasks = true --- @settings if true then the user who made the task can edit it regardless of the allow_edit_task setting } \ No newline at end of file diff --git a/config/warps.lua b/config/warps.lua index fb620108..d1710ba8 100644 --- a/config/warps.lua +++ b/config/warps.lua @@ -2,24 +2,39 @@ -- @config Warps return { - recharge_time = 60, --- @setting recharge_time The amount of time in seconds that the player must wait between warps, acts as a balance - update_smoothing = 10, --- @setting update_smoothing Higher is better, the amount of smoothing applied to recharge timer and other gui updates, max is 60 - minimum_distance = 100, --- @setting minimum_distance The minimum distance that must be between warp points, creating new ones is blocked when too close - activation_range = 4, --- @setting activation_range The distance the player must be to a warp in order to use the warp gui, gui can still be viewed but not used - spawn_activation_range = 20, --- @setting spawn_activation_range A second activation range which is used for the forces spawn point - default_icon = 'discharge-defense-equipment', --- @setting default_icon The default icon which is used by warps; must be an item name - user_can_edit_own_warps = false, --- @setting user_can_edit_own_warps When true the user can always edit warps which they created regardless of other settings - any_user_can_add_new_warp = false, --- @setting any_user_can_add_new_warp When true any user is able to create new warps, however editing may still be restricted - only_admins_can_edit = false, --- @setting only_admins_can_edit When true only admins can edit warps - edit_warps_role_permission = 'gui/warp-list/edit', --- @setting edit_warps_role_permission Role permission used by the role system to allow editing warps - bypass_warp_limits_permission = 'gui/warp-list/no-limit', --- @setting bypass_warp_limits_permission Role permission used by the role system to allow bypassing the time and distance restrictions - entities = { --- @setting entities The entities which are created for warps + -- General config + update_smoothing = 10, --- @setting update_smoothing the amount of smoothing applied to updates to the cooldown timer, higher is better, max is 60 + minimum_distance = 100, --- @setting minimum_distance the minimum distance that is allowed between warps on the same force + default_icon = 'discharge-defense-equipment', --- @setting default_icon the default icon that will be used for warps + + -- Warp cooldowns + bypass_warp_cooldown = 'expcore.roles', --- @setting bypass_warp_cooldown dictates who the warp cooldown is applied to; values: all, admin, expcore.roles, none + expcore_roles_bypass_warp_cooldown = 'gui/warp-list/bypass-cooldown', --- @setting expcore_roles_bypass_warp_cooldown if expcore.roles is used then this is the required permission + cooldown_duraction = 60, --- @setting cooldown_duraction the duration of the warp cooldown in seconds + + -- Warp proximity + bypass_warp_proximity = 'expcore.roles', --- @setting bypass_warp_proximity dictates who the warp proximity is applied to; values: all, admin, expcore.roles, none + expcore_roles_bypass_warp_proximity = 'gui/warp-list/bypass-proximity', --- @setting expcore_roles_bypass_warp_proximity if expcore.roles is used then this is the required permission + standard_proximity_radius = 4, --- @setting standard_proximity_radius the minimum distance a player is allowed to be to a warp in order to use it + spawn_proximity_radius = 20, --- @setting spawn_proximity_radius the minimum distance a player is allowed to be from they spawn point to use warps + + -- Adding warps + allow_add_warp = 'expcore.roles', --- @setting allow_add_warp dictates who is allowed to add warps; values: all, admin, expcore.roles, none + expcore_roles_allow_add_warp = 'gui/warp-list/add', --- @setting expcore_roles_allow_add_warp if expcore.roles is used then this is the required permission + + -- Editing warps + allow_edit_warp = 'expcore.roles', --- @setting allow_edit_warp dictates who is allowed to edit warps; values: all, admin, expcore.roles, none + expcore_roles_allow_edit_warp = 'gui/warp-list/edit', --- @setting expcore_roles_allow_edit_warp if expcore.roles is used then this is the required permission + user_can_edit_own_warps = false, --- @settings user_can_edit_own_warps if true then the user who made the warp can edit it regardless of the allow_edit_warp setting + + -- Warp area generation + entities = { --- @setting entities The entities which are created for warp areas {'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} }, - base_tile = 'tutorial-grid', --- @setting base_tile The tile which is used for the warps - tiles = { --- @setting tiles The tiles which are created for warps + base_tile = 'tutorial-grid', --- @setting base_tile The tile which is used for the warp areas + tiles = { --- @setting tiles The tiles which are created for warp areas {-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} } diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index 4fc1a161..a94550d3 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -348,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index 31bafcd7..5104f56d 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index 740ed70e..12b2d4b7 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index 6fb21b76..eda52288 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index 4f5b7ae2..a9885689 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index 8983690a..20304e86 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index e0085ca5..b5db145a 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -460,7 +460,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index 5de171a9..b6c03a49 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index 08b4fc10..8a822e46 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index dcc7f831..1beb5873 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 54a470ef..0545406e 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 894d9fd7..2cd5e62f 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index bb480f1c..7ed81faf 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -500,7 +500,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index 11a3faa5..9fe4825c 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -361,7 +361,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index fb090d39..d14c747d 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index 1960d836..c774d4d6 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -365,7 +365,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index ac910592..5eae53a7 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index 5488f96a..b69015ea 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index 371db9aa..4f5e97b4 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -458,7 +458,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index ef15886c..5f0aa397 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 5f07e558..15d03b28 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -611,7 +611,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index a892d1aa..d857f4de 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index c6e4fa94..a1e124e2 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index d7dd8363..d81a5601 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index 6225e155..89d221c1 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -321,7 +321,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index 2c739395..68d1dbac 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index d94c73f6..e76ebc00 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -557,7 +557,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index 24f01cf0..ae86a1c8 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index 2dd125fd..1308a173 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -443,7 +443,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index 8a4262f3..3766b23a 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -484,7 +484,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index 884b4a42..f6b81295 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -569,7 +569,7 @@ generated by LDoc diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index 7d0e5d3d..edadff82 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -506,7 +506,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index 9612f09e..93bd8e14 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index 021275cd..0dda65b9 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -485,7 +485,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index dd7c7ddb..82cc7f4b 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -294,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index 689ef12e..f4b77ef8 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index 9f3db256..d72f5edf 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index de12ef31..00353bdc 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index 76a3b440..5cd6e37d 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -338,7 +338,7 @@ see ./expcore/commands.lua for more details

    generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index d3162a9e..c1e53996 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index 38e0eee2..e345fe69 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index f9d7156b..27950dfa 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 9331d05b..9f00aa0c 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -240,7 +240,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index 3deb9a8e..c794811b 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -295,7 +295,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index 2d91ee39..ae73091b 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -812,7 +812,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index 64fa59aa..6251d78c 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index f648a0f5..c39118c6 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index 267b19c9..af464cc2 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -324,7 +324,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index 0449a9f1..858ae123 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index 8d50f302..d8c76b79 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -834,7 +834,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index 33b1ba00..f08ad41d 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -292,7 +292,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index 6aa0aa00..0abe99c3 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index df64e68c..5c8300dc 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index 0cd0d9f7..46f1ca96 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -744,7 +744,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index 8a8ae44b..4b21194e 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -244,13 +244,13 @@ allow_add_task - expcore_roles_add_permission + expcore_roles_allow_add_task allow_edit_task - expcore_roles_edit_permission + expcore_roles_allow_edit_task @@ -291,16 +291,15 @@
    - # - expcore_roles_add_permission + # + expcore_roles_allow_add_task

    -

    if expcore.roles is used then this is the required permission - values can be all, admin, expcore.roles, none

    +

    if expcore.roles is used then this is the required permission

    @@ -346,8 +345,8 @@
    - # - expcore_roles_edit_permission + # + expcore_roles_allow_edit_task
    @@ -385,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index 2a237eb2..e1fb3569 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -355,7 +355,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index 5ef899b2..723c7258 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -241,37 +241,46 @@ - recharge_time - - update_smoothing minimum_distance - activation_range - - - spawn_activation_range - - default_icon - user_can_edit_own_warps + bypass_warp_cooldown - any_user_can_add_new_warp + expcore_roles_bypass_warp_cooldown - only_admins_can_edit + cooldown_duraction - edit_warps_role_permission + bypass_warp_proximity - bypass_warp_limits_permission + expcore_roles_bypass_warp_proximity + + + standard_proximity_radius + + + spawn_proximity_radius + + + allow_add_warp + + + expcore_roles_allow_add_warp + + + allow_edit_warp + + + expcore_roles_allow_edit_warp entities @@ -294,33 +303,6 @@
    - # - recharge_time -
    -
    -
    -
    - -

    -

    The amount of time in seconds that the player must wait between warps, acts as a balance

    - - - - - - - - - - - - - - -
    -
    -
    -
    # update_smoothing
    @@ -329,7 +311,7 @@

    -

    Higher is better, the amount of smoothing applied to recharge timer and other gui updates, max is 60

    +

    the amount of smoothing applied to updates to the cooldown timer, higher is better

    @@ -356,61 +338,7 @@

    -

    The minimum distance that must be between warp points, creating new ones is blocked when too close

    - - - - - - - - - - - - - - - -
    -
    -
    - # - activation_range -
    -
    -
    -
    - -

    -

    The distance the player must be to a warp in order to use the warp gui, gui can still be viewed but not used

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - spawn_activation_range -
    -
    -
    -
    - -

    -

    A second activation range which is used for the forces spawn point

    +

    the minimum distance that is allowed between warps on the same force

    @@ -437,7 +365,7 @@

    -

    The default icon which is used by warps; must be an item name

    +

    the default icon that will be used for warps

    @@ -456,15 +384,15 @@
    - # - user_can_edit_own_warps + # + bypass_warp_cooldown

    -

    When true the user can always edit warps which they created regardless of other settings

    +

    dictates who the warp cooldown is applied to; values: all, admin, expcore.roles, none

    @@ -483,15 +411,15 @@
    - # - any_user_can_add_new_warp + # + expcore_roles_bypass_warp_cooldown

    -

    When true any user is able to create new warps, however editing may still be restricted

    +

    if expcore.roles is used then this is the required permission

    @@ -510,15 +438,15 @@
    - # - only_admins_can_edit + # + cooldown_duraction

    -

    When true only admins can edit warps

    +

    the duration of the warp cooldown in seconds

    @@ -537,15 +465,15 @@
    - # - edit_warps_role_permission + # + bypass_warp_proximity

    -

    Role permission used by the role system to allow editing warps

    +

    dictates who the warp proximity is applied to; values: all, admin, expcore.roles, none

    @@ -564,15 +492,177 @@
    - # - bypass_warp_limits_permission + # + expcore_roles_bypass_warp_proximity

    -

    Role permission used by the role system to allow bypassing the time and distance restrictions

    +

    if expcore.roles is used then this is the required permission

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + standard_proximity_radius +
    +
    +
    +
    + +

    +

    the minimum distance a player is allowed to be to a warp in order to use it

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + spawn_proximity_radius +
    +
    +
    +
    + +

    +

    the minimum distance a player is allowed to be from they spawn point to use warps

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + allow_add_warp +
    +
    +
    +
    + +

    +

    dictates who is allowed to add warps; values: all, admin, expcore.roles, none

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + expcore_roles_allow_add_warp +
    +
    +
    +
    + +

    +

    if expcore.roles is used then this is the required permission

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + allow_edit_warp +
    +
    +
    +
    + +

    +

    dictates who is allowed to edit warps; values: all, admin, expcore.roles, none

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + expcore_roles_allow_edit_warp +
    +
    +
    +
    + +

    +

    if expcore.roles is used then this is the required permission

    @@ -599,7 +689,7 @@

    -

    The entities which are created for warps

    +

    The entities which are created for warp areas

    @@ -626,7 +716,7 @@

    -

    The tile which is used for the warps

    +

    The tile which is used for the warp areas

    @@ -653,7 +743,7 @@

    -

    The tiles which are created for warps

    +

    The tiles which are created for warp areas

    @@ -684,7 +774,7 @@ generated by LDoc
    diff --git a/docs/control/Jail.html b/docs/control/Jail.html index a809745f..65aeb8d0 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -1208,7 +1208,7 @@ generated by LDoc
    diff --git a/docs/control/Production.html b/docs/control/Production.html index 12a57823..252850bf 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -1329,7 +1329,7 @@ generated by LDoc diff --git a/docs/control/Reports.html b/docs/control/Reports.html index a239a42c..c722290a 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -1110,7 +1110,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index a11e1edc..b53870c6 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -984,7 +984,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index cbe14682..64a3b413 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -998,7 +998,7 @@ Tasks.update_task(task_id,'We need more iron!',game. generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index 84f5e53c..31e9150f 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -1465,7 +1465,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index 16a7f9de..6580b84a 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -1563,7 +1563,7 @@ Warps.make_warp_tag(warp_id) generated by LDoc diff --git a/docs/core/Commands.html b/docs/core/Commands.html index 545ac82f..3a2e7a33 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -1972,7 +1972,7 @@ generated by LDoc diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index fedadfc1..dab10ae9 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -2746,7 +2746,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Gui.html b/docs/core/Gui.html index c438edc4..21d1c537 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -2851,7 +2851,7 @@ Gui.element{ generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index 13bacb25..bf67317a 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -1432,7 +1432,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index cfb25893..3beabbe4 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -3152,7 +3152,7 @@ generated by LDoc diff --git a/docs/core/Store.html b/docs/core/Store.html index f5eb98bb..5cf287d0 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -1481,7 +1481,7 @@ Store.set(player_scores,game.player,10) generated by LDoc diff --git a/docs/core/Sudo.html b/docs/core/Sudo.html index 9a0a180b..479ac70d 100644 --- a/docs/core/Sudo.html +++ b/docs/core/Sudo.html @@ -544,7 +544,7 @@ generated by LDoc diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index e0e633ba..be347756 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -626,7 +626,7 @@ generated by LDoc diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index 5714de34..2c0e4c87 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -629,7 +629,7 @@ generated by LDoc diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 12c80988..3ba61f51 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -449,7 +449,7 @@ generated by LDoc diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index a16009c7..6136165e 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -274,6 +274,18 @@ Button displayed in the ehader bar, used to add a new task + edit_task + Button displayed next to tasks which the user is can edit, used to start editing a task + + + discard_task + Button displayed next to tasks which the user is can edit, used to delete a task from the list + + + add_task_base + Set of three elements which make up each row of the task table + + confirm_edit Button displayed next to tasks which the user is currently editing, used to save changes @@ -282,26 +294,14 @@ Button displayed next to tasks which the user is currently editing, used to discard changes - discard_task - Button displayed next to tasks which the user is can edit, used to delete a task from the list - - - edit_task - Button displayed next to tasks which the user is can edit, used to start editing a task - - - add_task_base - Set of three elements which make up each row of the task table + task_editing + Editing state for a task, contrins a text field and the two edit buttons task_label Default state for a task, contains only a label with the task message - task_editing - Editing state for a task, contrins a text field and the two edit buttons - - task_list_container Main task list container for the left flow @@ -491,6 +491,87 @@ + + + + + + +
    +
    +
    +
    + # + edit_task +
    +
    +
    +
    + +

    Button displayed next to tasks which the user is can edit, used to start editing a task

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + discard_task +
    +
    +
    +
    + +

    Button displayed next to tasks which the user is can edit, used to delete a task from the list

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + add_task_base +
    +
    +
    +
    + +

    Set of three elements which make up each row of the task table

    +

    + + + + + + + + @@ -555,68 +636,14 @@
    - # - discard_task + # + task_editing
    -

    Button displayed next to tasks which the user is can edit, used to delete a task from the list

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - edit_task -
    -
    -
    -
    - -

    Button displayed next to tasks which the user is can edit, used to start editing a task

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - add_task_base -
    -
    -
    -
    - -

    Set of three elements which make up each row of the task table

    +

    Editing state for a task, contrins a text field and the two edit buttons

    @@ -653,33 +680,6 @@ - - - - - - -
    -
    -
    -
    - # - task_editing -
    -
    -
    -
    - -

    Editing state for a task, contrins a text field and the two edit buttons

    -

    - - - - - - - - @@ -756,7 +756,7 @@ generated by LDoc
    diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index 18297a4b..db64af56 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -282,30 +282,10 @@ - zoom_to_map - Used on the name label to allow zoom to map - - - warp_timer - This timer controls when a player is able to warp, eg every 60 seconds - - - goto_warp - When the button is clicked it will teleport the player - - add_new_warp Will add a new warp to the list, checks if the player is too close to an existing one - confirm_edit - Confirms the edit to name or icon of the warp - - - cancel_edit - Cancels the editing changes of the selected warp name or icon - - discard_warp Removes a warp from the list, including the physical area and map tag @@ -314,8 +294,44 @@ Opens edit mode for the warp - warp_list - Registers the warp list + add_warp_base + Set of three elements which make up each row of the warp table + + + confirm_edit + Confirms the edit to name or icon of the warp + + + cancel_edit + Cancels the editing changes of the selected warp name or icon + + + warp_editing + Editing state for a warp, contrins a text field and the two edit buttons + + + warp_label + Default state for a warp, contains only a label with the warp name + + + warp_icon_button + Default state for the warp icon, when pressed teleports the player + + + warp_icon_editing + Editing state for the warp icon, chose elem used to chosse icon + + + warp_timer + This timer controls when a player is able to warp, eg every 60 seconds + + + warp_list_container + Main warp list container for the left flow + + + warp_list_toggle + Button on the top flow used to toggle the warp list container @@ -582,87 +598,6 @@
    - # - zoom_to_map -
    -
    -
    -
    - -

    Used on the name label to allow zoom to map

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - warp_timer -
    -
    -
    -
    - -

    This timer controls when a player is able to warp, eg every 60 seconds

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - goto_warp -
    -
    -
    -
    - -

    When the button is clicked it will teleport the player

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    # add_new_warp
    @@ -680,60 +615,6 @@ - - - - - - - -
    -
    -
    - # - confirm_edit -
    -
    -
    -
    - -

    Confirms the edit to name or icon of the warp

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - cancel_edit -
    -
    -
    -
    - -

    Cancels the editing changes of the selected warp name or icon

    -

    - - - - - - - - @@ -798,14 +679,257 @@
    - # - warp_list + # + add_warp_base
    -

    Registers the warp list

    +

    Set of three elements which make up each row of the warp table

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + confirm_edit +
    +
    +
    +
    + +

    Confirms the edit to name or icon of the warp

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + cancel_edit +
    +
    +
    +
    + +

    Cancels the editing changes of the selected warp name or icon

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_editing +
    +
    +
    +
    + +

    Editing state for a warp, contrins a text field and the two edit buttons

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_label +
    +
    +
    +
    + +

    Default state for a warp, contains only a label with the warp name

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_icon_button +
    +
    +
    +
    + +

    Default state for the warp icon, when pressed teleports the player

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_icon_editing +
    +
    +
    +
    + +

    Editing state for the warp icon, chose elem used to chosse icon

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_timer +
    +
    +
    +
    + +

    This timer controls when a player is able to warp, eg every 60 seconds

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_list_container +
    +
    +
    +
    + +

    Main warp list container for the left flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + warp_list_toggle +
    +
    +
    +
    + +

    Button on the top flow used to toggle the warp list container

    @@ -837,7 +961,7 @@ generated by LDoc
    diff --git a/docs/index.html b/docs/index.html index a5e3d006..6154fead 100644 --- a/docs/index.html +++ b/docs/index.html @@ -511,7 +511,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index 6cca966d..a712091a 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -351,7 +351,7 @@ generated by LDoc diff --git a/docs/modules/utils.alien_evolution_progress.html b/docs/modules/utils.alien_evolution_progress.html index 6291b757..3ffd68e8 100644 --- a/docs/modules/utils.alien_evolution_progress.html +++ b/docs/modules/utils.alien_evolution_progress.html @@ -419,7 +419,7 @@ fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on generated by LDoc diff --git a/docs/modules/utils.core.html b/docs/modules/utils.core.html index b6393f5d..48b74c3f 100644 --- a/docs/modules/utils.core.html +++ b/docs/modules/utils.core.html @@ -1164,7 +1164,7 @@ generated by LDoc diff --git a/docs/modules/utils.debug.html b/docs/modules/utils.debug.html index c5882630..b34baf22 100644 --- a/docs/modules/utils.debug.html +++ b/docs/modules/utils.debug.html @@ -654,7 +654,7 @@ generated by LDoc diff --git a/docs/modules/utils.dump_env.html b/docs/modules/utils.dump_env.html index 2927bed7..42ee92fc 100644 --- a/docs/modules/utils.dump_env.html +++ b/docs/modules/utils.dump_env.html @@ -323,7 +323,7 @@ generated by LDoc diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index 49848f9e..f851a4f8 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -1292,7 +1292,7 @@ generated by LDoc diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index ec13ecfc..aed7f3cf 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -434,7 +434,7 @@ generated by LDoc diff --git a/docs/modules/utils.math.html b/docs/modules/utils.math.html index e4815bc6..f72252fd 100644 --- a/docs/modules/utils.math.html +++ b/docs/modules/utils.math.html @@ -353,7 +353,7 @@ generated by LDoc diff --git a/docs/modules/utils.recipe_locker.html b/docs/modules/utils.recipe_locker.html index 717e7598..20e6ef12 100644 --- a/docs/modules/utils.recipe_locker.html +++ b/docs/modules/utils.recipe_locker.html @@ -441,7 +441,7 @@ generated by LDoc diff --git a/docs/modules/utils.state_machine.html b/docs/modules/utils.state_machine.html index aeb9fd7f..9fe3a7ae 100644 --- a/docs/modules/utils.state_machine.html +++ b/docs/modules/utils.state_machine.html @@ -752,7 +752,7 @@ generated by LDoc diff --git a/docs/modules/utils.table.html b/docs/modules/utils.table.html index 13f18afb..d7c02aa1 100644 --- a/docs/modules/utils.table.html +++ b/docs/modules/utils.table.html @@ -1418,7 +1418,7 @@ generated by LDoc diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index 47a1f7d6..dda2c43f 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -651,7 +651,7 @@ generated by LDoc diff --git a/docs/modules/utils.timestamp.html b/docs/modules/utils.timestamp.html index df8680e8..98b6d7f3 100644 --- a/docs/modules/utils.timestamp.html +++ b/docs/modules/utils.timestamp.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index ffb5dd8e..2d42a575 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -789,7 +789,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index 7dba1a3c..4284e0e5 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -338,7 +338,7 @@ Please report these errors to [the issues page](issues). generated by LDoc diff --git a/expcore/gui.lua b/expcore/gui.lua index 96193316..70af10f9 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -411,15 +411,15 @@ Gui.toggle_top_flow(game.player,true) function Gui.toggle_top_flow(player,state) local top_flow = Gui.get_top_flow(player) local toggle_button = top_flow[toggle_top_flow.name] - local new_state = state or toggle_button.style.name == 'forward_button' + if state == nil then state = toggle_button.style.name == 'forward_button' end -- Set the visible state of all elements in the flow for name,authenticator in pairs(Gui.top_elements) do - top_flow[name].visible = new_state and authenticator(player) or false + top_flow[name].visible = state and authenticator(player) or false end -- Change the style of the toggle button - if new_state then + if state then toggle_button.style = 'back_button' local style = toggle_button.style style.height = 36 @@ -431,7 +431,7 @@ function Gui.toggle_top_flow(player,state) style.width = 18 end - return new_state + return state end --- Left Flow. @@ -501,8 +501,8 @@ function Gui.toggle_left_element(player,element_define,state) -- Set the visible state local element = left_flow[element_define.name] - local new_state = state or not element.visible - element.visible = new_state + if state == nil then state = not element.visible end + element.visible = state -- Check if the hide button should be visible local show_hide_button = false @@ -514,11 +514,11 @@ function Gui.toggle_left_element(player,element_define,state) end hide_button.visible = show_hide_button - return new_state + return state end -- Draw the two flows when a player joins -Event.add(defines.events.on_player_joined_game,function(event) +Event.add(defines.events.on_player_created,function(event) local player = game.players[event.player_index] -- Draw the top flow @@ -581,9 +581,9 @@ local new_enabled_state = Gui.toggle_enabled_state(element) ]] function Gui.toggle_enabled_state(element,state) if not element or not element.valid then return end - local new_state = state or not element.enabled - element.enabled = new_state - return new_state + if state == nil then state = not element.enabled end + element.enabled = state + return state end --[[-- Will toggle the visible state of an element or set it to the one given @@ -597,9 +597,9 @@ local new_visible_state = Gui.toggle_visible_state(element) ]] function Gui.toggle_visible_state(element,state) if not element or not element.valid then return end - local new_state = state or not element.visible - element.visible = new_state - return new_state + if state == nil then state = not element.visible end + element.visible = state + return state end --[[-- Destory a gui element without causing any errors, likly if the element may have already been removed diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 91d1faf2..332d2f42 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -91,7 +91,7 @@ cancel-tooltip=Discard changes edit-tooltip=Currently being edited by: __1__ edit-tooltip-none=Currently being edited by: Nobody discard-tooltip=Remove warp -timer-tooltip=Warp charge, charge time __1__ seconds +timer-tooltip=Warp cooldown takes __1__ seconds goto-tooltip=Go to x __1__ y __2__ goto-disabled=You must be on a warp point and have a full charge to warp goto-edit=Edit warp icon diff --git a/modules/control/warps.lua b/modules/control/warps.lua index ad503c3a..8958c833 100644 --- a/modules/control/warps.lua +++ b/modules/control/warps.lua @@ -150,7 +150,7 @@ function Warps.make_warp_area(warp_id) local position = warp.position local posx = position.x local posy = position.y - local radius = config.activation_range + local radius = config.standard_proximity_radius local radius2 = radius^2 -- Get the tile that is being replaced, store.update not needed as we dont want it to trigger @@ -203,7 +203,7 @@ function Warps.remove_warp_area(warp_id) local warp = Store.get(warp_store,warp_id) local position = warp.position local surface = warp.surface - local radius = config.activation_range + local radius = config.standard_proximity_radius local radius2 = radius^2 -- Check that a warp area was created previously diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index c36c3422..68baedae 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -333,7 +333,9 @@ Gui.element(function(event_trigger,parent) } -- Set the frame style - frame.style.padding = 2 + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 -- Draw the internal container local container = diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index d5d12a4f..f39c562d 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -20,6 +20,11 @@ local player_in_range_store = Store.register(function(player) return player.name end) +-- Stores the time remaing for a players warp cooldown +local player_warp_cooldown_store = Store.register(function(player) + return player.name +end) + -- Table that stores a boolean value of weather to keep the warp gui open local keep_gui_open = {} Global.register(keep_gui_open,function(tbl) @@ -27,130 +32,160 @@ Global.register(keep_gui_open,function(tbl) end) --- Returns if a player is allowed to edit the given warp -local function player_allowed_edit(player,warp) - if warp then +--- If a player is allowed to use the edit buttons +local function check_player_permissions(player,action,warp) + -- Check if the action is allow edit and then check bypass settings + if action == 'allow_edit_warp' then + -- Check if the warp is the spawn then it cant be edited local spawn_id = Warps.get_spawn_warp_id(player.force.name) if spawn_id == warp.warp_id then return false end + + -- Check if the player being the last to edit will override existing permisisons if config.user_can_edit_own_warps and warp.last_edit_name == player.name then return true end - else - if config.any_user_can_add_new_warp then - return true - end end - if config.only_admins_can_edit and not player.admin then - return false + -- Check player has permisison based on value in the config + local action_config = config[action] + if action_config == 'all' then + return true + elseif action_config == 'admin' then + return player.admin + elseif action_config == 'expcore.roles' then + return Roles.player_allowed(player,config['expcore_roles_'..action]) end - if config.edit_warps_role_permission and not Roles.player_allowed(player,config.edit_warps_role_permission) then - return false - end - - return true + -- Return false as all other condidtions have not been met + return false end ---- Used on the name label to allow zoom to map --- @element zoom_to_map -local zoom_to_map_name = Gui.uid_name() -Gui.on_click(zoom_to_map_name,function(event) - local warp_id = event.element.parent.name - local warp = Warps.get_warp(warp_id) - local position = warp.position - event.player.zoom_to_world(position,1.5) -end) - - ---- This timer controls when a player is able to warp, eg every 60 seconds --- @element warp_timer -local warp_timer = -Gui.new_progressbar() -:set_tooltip{'warp-list.timer-tooltip',config.recharge_time} -:set_default_maximum(math.floor(config.recharge_time*config.update_smoothing)) -:add_store(Gui.categorize_by_player) -:set_style(nil,function(style) - style.horizontally_stretchable = true - style.color = Colors.light_blue -end) -:on_store_complete(function(player_name,reset) - Store.trigger(player_in_range_store,player_name) -end) - ---- When the button is clicked it will teleport the player --- @element goto_warp -local goto_warp = -Gui.new_button() -:set_sprites('item/'..config.default_icon) -:set_tooltip{'warp-list.goto-tooltip',0,0} -:set_style('quick_bar_slot_button',function(style) - style.height = 32 - style.width = 32 -end) -:on_click(function(player,element) - local warp_id = element.parent.caption - Warps.teleport_player(warp_id,player) - - -- Reset the warp cooldown if the player does not have unlimited warps - if config.bypass_warp_limits_permission and not Roles.player_allowed(player,config.bypass_warp_limits_permission) then - warp_timer:set_store(player.name,0) - Store.trigger(player_in_range_store,player) - end -end) - --- Will add a new warp to the list, checks if the player is too close to an existing one -- @element add_new_warp local add_new_warp = -Gui.new_button() -:set_sprites('utility/add') -:set_tooltip{'warp-list.add-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/add', + tooltip = {'warp-list.add-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} :on_click(function(player,element) + -- Add the new warp local force_name = player.force.name local surface = player.surface local position = player.position - local px = position.x - local py = position.y - local dist2 = config.minimum_distance^2 - - -- Check the distance to all existing warps - local warp_ids = Warps.get_force_warp_ids(force_name) - for _,warp_id in pairs(warp_ids) do - local warp = Warps.get_warp(warp_id) - local pos = warp.position - if surface == warp.surface and (px-pos.x)^2+(py-pos.y)^2 < dist2 then - player.print{'warp-list.too-close',warp.name} - return - end - end - - -- Add the new warp local warp_id = Warps.add_warp(force_name,surface,position,player.name) Warps.make_warp_tag(warp_id) Warps.make_warp_area(warp_id) end) +--- Removes a warp from the list, including the physical area and map tag +-- @element discard_warp +local discard_warp = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/trash', + tooltip = {'warp-list.discard-tooltip'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(_,element) + local warp_id = element.parent.name:sub(6) + Warps.remove_warp(warp_id) +end) + +--- Opens edit mode for the warp +-- @element edit_warp +local edit_warp = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/rename_icon_normal', + tooltip = {'warp-list.edit-tooltip-none'}, + style = 'tool_button' +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element) + local warp_id = element.parent.name:sub(6) + Warps.set_editing(warp_id,player.name,true) +end) + +--- Set of three elements which make up each row of the warp table +-- @element add_warp_base +local add_warp_base = +Gui.element(function(_,parent,warp_id) + -- Add the icon flow + local icon_flow = + parent.add{ + name = 'icon-'..warp_id, + type = 'flow', + caption = warp_id + } + + -- Change the style of the flow + icon_flow.style.padding = 0 + + -- Add a flow which will contain the warp name and edit buttons + local warp_flow = + parent.add{ + name = warp_id, + type = 'flow', + } + + -- Set the padding on the warp flow + warp_flow.style.padding = 0 + + -- Add the two edit buttons outside the warp flow + local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..warp_id) + edit_warp(edit_flow) + discard_warp(edit_flow) + + -- Return the warp flow as the main element + return warp_flow +end) + +-- Removes the three elements that are added as part of the warp base +local function remove_warp_base(parent,warp_id) + Gui.destroy_if_valid(parent['icon-'..warp_id]) + Gui.destroy_if_valid(parent['edit-'..warp_id]) + Gui.destroy_if_valid(parent[warp_id]) +end + --- Confirms the edit to name or icon of the warp -- @element confirm_edit +local warp_editing +local warp_icon_button local confirm_edit = -Gui.new_button() -:set_sprites('utility/downloaded') -:set_tooltip{'warp-list.confirm-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/downloaded', + tooltip = {'warp-list.confirm-tooltip'}, + style = 'shortcut_bar_button_green' +} +:style{ + padding = -2, + right_margin = -3, + height = 22, + width = 22 +} :on_click(function(player,element) local warp_id = element.parent.name - local warp_name = element.parent.warp.text - local warp_icon = element.parent.parent['icon-'..warp_id].icon.elem_value + local warp_name = element.parent[warp_editing.name].text + local warp_icon = element.parent.parent['icon-'..warp_id][warp_icon_button.name].elem_value Warps.set_editing(warp_id,player.name) Warps.update_warp(warp_id,warp_name,warp_icon,player.name) end) @@ -158,360 +193,462 @@ end) --- Cancels the editing changes of the selected warp name or icon -- @element cancel_edit local cancel_edit = -Gui.new_button() -:set_sprites('utility/close_black') -:set_tooltip{'warp-list.cancel-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + tooltip = {'warp-list.cancel-tooltip'}, + style = 'shortcut_bar_button_red' +} +:style{ + padding = -2, + right_margin = -3, + height = 22, + width = 22 +} :on_click(function(player,element) local warp_id = element.parent.name Warps.set_editing(warp_id,player.name) end) ---- Removes a warp from the list, including the physical area and map tag --- @element discard_warp -local discard_warp = -Gui.new_button() -:set_sprites('utility/trash') -:set_tooltip{'warp-list.discard-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) +--- Editing state for a warp, contrins a text field and the two edit buttons +-- @element warp_editing +warp_editing = +Gui.element(function(event_trigger,parent,warp) + local name = warp.name + + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'textfield', + text = name, + clear_and_focus_on_right_click = true + } + + -- Change the style + local style = element.style + style.maximal_width = 110 style.height = 20 - style.width = 20 + + -- Add the edit buttons + cancel_edit(parent) + confirm_edit(parent) + + -- Return the element + return element end) -:on_click(function(player,element) +:on_confirmed(function(player,element,_) local warp_id = element.parent.name - Warps.remove_warp(warp_id) + local warp_name = element.text + local warp_icon = element.parent.parent['icon-'..warp_id][warp_icon_button.name].elem_value + Warps.set_editing(warp_id,player.name) + Warps.update_warp(warp_id,warp_name,warp_icon,player.name) end) ---- Opens edit mode for the warp --- @element edit_warp -local edit_warp = -Gui.new_button() -:set_sprites('utility/rename_icon_normal') -:set_tooltip{'warp-list.edit-tooltip-none'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) - local warp_id = element.parent.name - Warps.set_editing(warp_id,player.name,true) -end) +--- Default state for a warp, contains only a label with the warp name +-- @element warp_label +local warp_label = +Gui.element(function(event_trigger,parent,warp) + local name = warp.name + local last_edit_name = warp.last_edit_name + local last_edit_time = warp.last_edit_time ---[[ Generates each warp, handles both view and edit mode - element - > icon-"warp_id" - >> goto_warp or icon - > "warp_id" - >> warp - >> cancel_edit (edit mode) - >> confirm_edit (edit mode) - > edit-"warp_id" - >> "warp_id" - >>> edit_warp - >>> discard_warp -]] -local function generate_warp(player,element,warp_id) + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'label', + caption = name, + tooltip = {'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} + } + + -- Change the style + local style = element.style + style.single_line = false + style.maximal_width = 150 + + -- Return the element + return element +end) +:on_click(function(player,element,_) + local warp_id = element.parent.name local warp = Warps.get_warp(warp_id) + local position = warp.position + player.zoom_to_world(position,1.5) +end) + + +--- Default state for the warp icon, when pressed teleports the player +-- @element warp_icon_button +warp_icon_button = +Gui.element(function(event_trigger,parent,warp) + local warp_position = warp.position + + -- Draw the element + local element = + parent.add{ + name = event_trigger, + type = 'sprite-button', + sprite = 'item/'..warp.icon, + tooltip = {'warp-list.goto-tooltip',warp_position.x,warp_position.y}, + style = 'quick_bar_slot_button' + } + + -- Change the style + local style = element.style + style.height = 32 + style.width = 32 + + -- Return the element + return element +end) +:on_click(function(player,element,_) + local warp_id = element.parent.caption + Warps.teleport_player(warp_id,player) + + -- Reset the warp cooldown if the player does not have unlimited warps + if not check_player_permissions(player,'bypass_warp_cooldown') then + Store.set(player_warp_cooldown_store,player,config.cooldown_duraction) + Store.trigger(player_in_range_store,player) + end +end) + +--- Editing state for the warp icon, chose elem used to chosse icon +-- @element warp_icon_editing +local warp_icon_editing = +Gui.element(function(event_trigger,parent,warp) + local warp_icon = warp.icon + + -- Draw the element + local element = + parent.add{ + name = warp_icon_button.name, + type = 'choose-elem-button', + elem_type = 'item', + item = warp_icon, + tooltip = {'warp-list.goto-edit'}, + } + + -- Change the style + local style = element.style + style.height = 32 + style.width = 32 + + -- Return the element + return element +end) + +--- This timer controls when a player is able to warp, eg every 60 seconds +-- @element warp_timer +local warp_timer = +Gui.element{ + type = 'progressbar', + tooltip = {'warp-list.timer-tooltip',config.cooldown_duraction}, + minimum_value = 0, + maximum_value = config.cooldown_duraction*config.update_smoothing +} +:style{ + horizontally_stretchable = true, + color = Colors.light_blue +} + +--- Updates a warp for a player +local function update_warp(player,warp_table,warp_id) + local warp = Warps.get_warp(warp_id) + + -- Warp no longer exists so should be removed from the list if not warp then - -- warp is nil so remove it from the list - Gui.destroy_if_valid(element['icon-'..warp_id]) - Gui.destroy_if_valid(element['edit-'..warp_id]) - Gui.destroy_if_valid(element[warp_id]) - - else - local warp_name = warp.name - local warp_icon = warp.icon - local editing = warp.currently_editing[player.name] - local last_edit_name = warp.last_edit_name - local last_edit_time = warp.last_edit_time - local position = warp.position - - -- if it is not already present then add it now - local warp_area = element[warp_id] - local icon_area = element['icon-'..warp_id] - if not warp_area then - -- area to store the warp icon - icon_area = - element.add{ - name='icon-'..warp_id, - type='flow', - caption=warp_id - } - Gui.set_padding(icon_area) - - -- area which stores the warp and buttons - warp_area = - element.add{ - name=warp_id, - type='flow', - } - Gui.set_padding(warp_area) - - -- if the player can edit then it adds the edit and delete button - local flow = Gui.create_alignment(element,'edit-'..warp_id) - local sub_flow = flow.add{type='flow',name=warp_id} - - edit_warp(sub_flow) - discard_warp(sub_flow) - - end - - local edit_area = element['edit-'..warp_id][warp_id] - local players = warp.currently_editing and table_keys(warp.currently_editing) or {} - local allowed = player_allowed_edit(player,warp) - - edit_area.visible = allowed - - if #players > 0 then - edit_area[edit_warp.name].tooltip = {'warp-list.edit-tooltip',table.concat(players,', ')} - else - edit_area[edit_warp.name].tooltip = {'warp-list.edit-tooltip-none'} - end - - -- draws/updates the warp area - local label_element = warp_area.warp or warp_area[zoom_to_map_name] or nil - local element_type = label_element and label_element.type or nil - if not editing and element_type == 'label' then - -- update the label already present - label_element.caption = warp_name - label_element.tooltip = {'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} - icon_area[goto_warp.name].sprite = 'item/'..warp_icon - - elseif not editing then - -- create the label, view mode - if edit_area then - edit_area[edit_warp.name].enabled = true - end - - -- redraws the icon for the warp - icon_area.clear() - - local btn = goto_warp(icon_area) - btn.sprite = 'item/'..warp_icon - btn.tooltip = {'warp-list.goto-tooltip',position.x,position.y} - - local timer = warp_timer:get_store(player.name) - local enabled = not timer and Store.get(player_in_range_store,player) - or Roles.player_allowed(player,config.bypass_warp_limits_permission) - if not enabled then - btn.enabled = false - btn.tooltip = {'warp-list.goto-disabled'} - end - - -- redraws the label for the warp name - warp_area.clear() - - local label = - warp_area.add{ - name=zoom_to_map_name, - type='label', - caption=warp_name, - tooltip={'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} - } - label.style.single_line = false - label.style.maximal_width = 150 - - elseif editing and element_type ~= 'textfield' then - -- create the text field, edit mode, update it omitted as value is being edited - if edit_area then - edit_area[edit_warp.name].enabled = false - end - - -- redraws the icon for the warp and allows selection - icon_area.clear() - - local btn = - icon_area.add{ - name='icon', - type='choose-elem-button', - elem_type='item', - item=warp_icon, - tooltip={'warp-list.goto-edit'}, - } - btn.style.height = 32 - btn.style.width = 32 - - -- redraws the label for the warp name and allows editing - warp_area.clear() - - local entry = - warp_area.add{ - name='warp', - type='textfield', - text=warp_name - } - entry.style.maximal_width = 150 - entry.style.height = 20 - - cancel_edit(warp_area) - confirm_edit(warp_area) - - end - + remove_warp_base(warp_table,warp_id) + return end + -- Get the warp flow for this warp + local warp_flow = warp_table[warp_id] or add_warp_base(warp_table,warp_id) + local icon_flow = warp_table['icon-'..warp_id] + + -- Update the edit flow + local edit_flow = warp_table['edit-'..warp_id] + local player_allowed_edit = check_player_permissions(player,'allow_edit_warp',warp) + local players_editing = table_keys(warp.currently_editing) + local edit_warp_element = edit_flow[edit_warp.name] + local discard_warp_element = edit_flow[discard_warp.name] + + edit_warp_element.visible = player_allowed_edit + discard_warp_element.visible = player_allowed_edit + if #players_editing > 0 then + edit_warp_element.hovered_sprite = 'utility/warning_icon' + edit_warp_element.tooltip = {'warp-list.edit-tooltip',table.concat(players_editing,', ')} + else + edit_warp_element.hovered_sprite = edit_warp_element.sprite + edit_warp_element.tooltip = {'warp-list.edit-tooltip-none'} + end + + -- Check if the player is was editing and/or currently editing + local warp_label_element = warp_flow[warp_label.name] or warp_label(warp_flow,warp) + local icon_entry = icon_flow[warp_icon_button.name] or warp_icon_button(icon_flow,warp) + local player_was_editing = icon_entry.type == 'choose-elem-button' + local player_is_editing = warp.currently_editing[player.name] + + -- Update the warp and icon flow + if not player_was_editing and not player_is_editing then + -- Update the warp name label and icon + local warp_name = warp.name + local warp_icon = warp.icon + local last_edit_name = warp.last_edit_name + local last_edit_time = warp.last_edit_time + warp_label_element.caption = warp_name + warp_label_element.tooltip = {'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} + icon_entry.sprite = 'item/'..warp_icon + + elseif player_was_editing and not player_is_editing then + -- Player was editing but is no longer, remove text field and add label + edit_warp_element.enabled = true + warp_flow.clear() + warp_label(warp_flow,warp) + + icon_flow.clear() + local warp_icon_element = warp_icon_button(icon_flow,warp) + local timer = Store.get(player_warp_cooldown_store,player) + local in_range = Store.get(player_in_range_store,player) + local apply_proximity = not check_player_permissions(player,'bypass_warp_proximity') + if (timer and timer > 0) or (apply_proximity and not in_range) then + warp_icon_element.enabled = false + warp_icon_element.tooltip = {'warp-list.goto-disabled'} + end + + elseif not player_was_editing and player_is_editing then + -- Player was not editing but now is, remove label and add text field + edit_warp_element.enabled = false + warp_flow.clear() + warp_editing(warp_flow,warp).focus() + icon_flow.clear() + warp_icon_editing(icon_flow,warp) + + end end ---[[ generates the main gui structure - element - > container - >> header - >>> right aligned add_new_warp - >> scroll - >>> table - >> warp_timer -]] -local function generate_container(player,element) - Gui.set_padding(element,2,2,2,2) - element.style.minimal_width = 200 +local function update_all_warps(player,warp_table) + local warp_ids = Warps.get_force_warp_ids(player.force.name) + if #warp_ids > 0 then + for _,warp_id in ipairs(warp_ids) do + update_warp(player,warp_table,warp_id) + end + end +end - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' +--- Main warp list container for the left flow +-- @element warp_list_container +local warp_list_container = +Gui.element(function(event_trigger,parent) + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' } - Gui.set_padding(container) - container.style.vertically_stretchable = false - -- main header for the gui - local header_area = Gui.create_header( + -- Set the frame style + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 + + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } + + -- Set the container style + local style = container.style + style.vertically_stretchable = false + + -- Draw the header + local header = Gui.header( container, {'warp-list.main-caption'}, - {'warp-list.sub-tooltip',config.recharge_time,config.activation_range}, + {'warp-list.sub-tooltip', config.cooldown_duraction, config.standard_proximity_radius}, true ) - --- Right aligned button to toggle the section - if player_allowed_edit(player) then - add_new_warp(header_area) + -- Draw the new warp button + local player = Gui.get_player_from_element(parent) + local add_new_warp_element = add_new_warp(header) + add_new_warp_element.visible = check_player_permissions(player,'allow_add_warp') + + -- Draw the scroll table for the warps + local scroll_table = Gui.scroll_table(container,258,3) + + -- Change the style of the scroll table + local scroll_table_style = scroll_table.style + scroll_table_style.top_cell_padding = 3 + scroll_table_style.bottom_cell_padding = 3 + + -- Draw the warp cooldown progress bar + local warp_timer_element = warp_timer(container) + + -- Change the progress of the warp timer + local progress = 1 + local timer = Store.get(player_warp_cooldown_store,player) + if timer and timer > 0 then + progress = 1 - (timer/config.cooldown_duraction) end + warp_timer_element.value = progress - -- table that stores all the data - local flow_table = Gui.create_scroll_table(container,3,258) - flow_table.style.top_cell_padding = 3 - flow_table.style.bottom_cell_padding = 3 + -- Add any existing warps + update_all_warps(player,scroll_table) - warp_timer(container) - - return flow_table -end - ---- Registers the warp list --- @element warp_list -local warp_list = -Gui.new_left_frame('gui/warp-list') -:set_sprites('item/'..config.default_icon) -:set_tooltip{'warp-list.main-tooltip',config.activation_range} -:set_direction('vertical') -:on_creation(function(player,element) - local data_table = generate_container(player,element) - local warp_ids = Warps.get_force_warp_ids(player.force.name) - - for _,warp_id in ipairs(warp_ids) do - generate_warp(player,data_table,warp_id) - end + -- Return the exteral container + return frame end) -:on_update(function(player,element) - local data_table = element.container.scroll.table - local warp_ids = Warps.get_force_warp_ids(player.force.name) +:add_to_left_flow() - data_table.clear() - for _,warp_id in ipairs(warp_ids) do - generate_warp(player,data_table,warp_id) - end +--- Button on the top flow used to toggle the warp list container +-- @element warp_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'item/'..config.default_icon, + tooltip = {'warp-list.main-tooltip',config.standard_proximity_radius}, + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/warp-list') end) -:on_player_toggle(function(player,element,visible) - keep_gui_open[player.name] = visible +:on_click(function(player,_,_) + local visible_state = Gui.toggle_left_element(player, warp_list_container) + keep_gui_open[player.name] = visible_state end) --- When the name of a warp is updated this is triggered -Warps.on_update(function(warp) - local players - local force_name +Warps.on_update(function(warp,_,removed_warp) + -- Get the force to update, warp is nil when removed + local force if warp then - local force = game.forces[warp.force_name] - players = force.connected_players - force_name = warp.force_name + force = game.forces[warp.force_name] else - players = game.connected_players + force = game.forces[removed_warp.force_name] end -- Update the gui for selected players - local force_warps = {} - for _,player in pairs(players) do - local frame = warp_list:get_frame(player) - local element = frame.container.scroll.table - - -- Get the warp ids for the players force - force_name = force_name or player.force.name - local warp_ids = force_warps[force_name] - if not warp_ids then - warp_ids = Warps.get_force_warp_ids(force_name) - force_warps[force_name] = warp_ids - end + local warp_ids = Warps.get_force_warp_ids(force.name) + for _,player in pairs(force.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local scroll_table = frame.container.scroll.table -- Update the gui - element.clear() - for _,warp_id in ipairs(warp_ids) do - generate_warp(player,element,warp_id) + scroll_table.clear() + for _,next_warp_id in ipairs(warp_ids) do + update_warp(player,scroll_table,next_warp_id) end end end) --- Update the warps when the player joins -Event.add(defines.events.on_player_joined_game,warp_list 'redraw') -Event.add(Roles.events.on_role_assigned,warp_list 'redraw') -Event.add(Roles.events.on_role_unassigned,warp_list 'redraw') +Event.add(defines.events.on_player_joined_game,function(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local scroll_table = frame.container.scroll.table + update_all_warps(player,scroll_table) +end) + +--- Makes sure the right buttons are present when roles change +local function role_update_event(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local container = left_flow[warp_list_container.name].container + + -- Update the warps, incase the user can now edit them + local scroll_table = container.scroll.table + update_all_warps(player,scroll_table) + + -- Update the new warp button incase the user can now add them + local add_new_warp_element = container.header.alignment[add_new_warp.name] + add_new_warp_element.visible = check_player_permissions(player,'allow_add_warp') +end + +Event.add(Roles.events.on_role_assigned,role_update_event) +Event.add(Roles.events.on_role_unassigned,role_update_event) --- When the player leaves or enters range of a warp this is triggered Store.watch(player_in_range_store,function(value,player_name) local player = game.players[player_name] local force = player.force - local frame = warp_list:get_frame(player_name) - local table_area = frame.container.scroll.table - local timer = warp_timer:get_store(player_name) - local state = not timer and value + -- Change if the frame is visible based on if the player is in range if not keep_gui_open[player.name] then - Gui.toggle_left_frame(warp_list.name,player,value) + Gui.toggle_left_element(player,warp_list_container,value) end - if Roles.player_allowed(player,config.bypass_warp_limits_permission) then + -- Check if the player requires proximity + if check_player_permissions(player,'bypass_warp_proximity') then return end + -- Get the warp table + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local scroll_table = frame.container.scroll.table + + -- Check if the buttons should be active + local timer = Store.get(player_warp_cooldown_store,player) + local button_disabled = timer and timer > 0 or not value + + -- Change the enabled state of the warp buttons local warp_ids = Warps.get_force_warp_ids(force.name) for _,warp_id in pairs(warp_ids) do - local element = table_area['icon-'..warp_id][goto_warp.name] + local element = scroll_table['icon-'..warp_id][warp_icon_button.name] if element and element.valid then - element.enabled = state - if state then + element.enabled = not button_disabled + if button_disabled then + element.tooltip = {'warp-list.goto-disabled'} + else local position = Warps.get_warp(warp_id).position element.tooltip = {'warp-list.goto-tooltip',position.x,position.y} - else - element.tooltip = {'warp-list.goto-disabled'} end end end end) ---- Handles updating the timer and checking distance from a warp -local r2 = config.activation_range^2 -local rs2 = config.spawn_activation_range^2 -Event.on_nth_tick(math.floor(60/config.update_smoothing),function() - local categories = Store.get(warp_timer.store) or {} - for category,_ in pairs(categories) do - warp_timer:increment(1,category) +--- Update the warp cooldown progress bars to match the store +Store.watch(player_warp_cooldown_store,function(value,player_name,old_value) + if value == old_value then return end + -- Get the progress bar element + local player = game.players[player_name] + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local warp_timer_element = frame.container[warp_timer.name] + + -- Set the progress + local progress = 1 + local timer = Store.get(player_warp_cooldown_store,player) + if timer and timer > 0 then + progress = 1 - (timer/config.cooldown_duraction) end + warp_timer_element.value = progress + + -- Trigger update of buttons if cooldown is now 0 + if value == 0 then + Store.trigger(player_in_range_store,player_name) + end +end) + +--- Handles updating the timer and checking distance from a warp +local r2 = config.standard_proximity_radius^2 +local rs2 = config.spawn_proximity_radius^2 +local mr2 = config.minimum_distance^2 +Event.on_nth_tick(math.floor(60/config.update_smoothing),function() + Store.map(player_warp_cooldown_store,function(value) + if value > 0 then + return value - 1 + end + end) local force_warps = {} local warps = {} @@ -527,6 +664,8 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing),function() end -- Check if the force has any warps + local closest_warp + local closest_distance if #warp_ids > 0 then local surface = player.surface local pos = player.position @@ -545,20 +684,35 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing),function() local warp_pos = warp.position if warp.surface == surface then local dx, dy = px-warp_pos.x, py-warp_pos.y - if (warp_id == warp_ids.spawn and (dx*dx)+(dy*dy) < rs2) or (dx*dx)+(dy*dy) < r2 then - -- Set in range to true if the player was preiovusly out of range - if not was_in_range then - Store.set(player_in_range_store,player,true) - end - was_in_range = false -- stops setting back to false below - break + local dist = (dx*dx)+(dy*dy) + if closest_distance == nil or dist < closest_distance then + closest_warp = warp + closest_distance = dist + if dist < r2 then break end end end end - -- Set in range to false if the player was preiovusly in range - if was_in_range then + -- Check the dist to the closest warp + local in_range = closest_warp.warp_id == warp_ids.spawn and closest_distance < rs2 or closest_distance < r2 + if was_in_range and not in_range then Store.set(player_in_range_store,player,false) + elseif not was_in_range and in_range then + Store.set(player_in_range_store,player,true) + end + + -- Change the enabled state of the add warp button + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[warp_list_container.name] + local add_warp_element = frame.container.header.alignment[add_new_warp.name] + local was_able_to_make_warp = add_warp_element.enabled + local can_make_warp = closest_distance > mr2 + if can_make_warp and not was_able_to_make_warp then + add_warp_element.enabled = true + add_warp_element.tooltip = {'warp-list.add-tooltip'} + elseif not can_make_warp and was_able_to_make_warp then + add_warp_element.enabled = false + add_warp_element.tooltip = {'warp-list.too-close',closest_warp.name} end end @@ -567,18 +721,10 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing),function() end) ---- When a player is created it will set them being in range to false to stop warping on join +--- When a player is created make sure that there is a spawn warp created Event.add(defines.events.on_player_created,function(event) - local player = Game.get_player_by_index(event.player_index) - - -- Check if a player is allowed unlimited warps - local allowed = config.bypass_warp_limits_permission and Roles.player_allowed(player,config.bypass_warp_limits_permission) or false - Store.set(player_in_range_store,player,allowed) - if allowed then - warp_timer:set_store(player.name,1) - end - -- If the force has no spawn then make a spawn warp + local player = Game.get_player_by_index(event.player_index) local force = player.force local spawn_id = Warps.get_spawn_warp_id(force.name) if not spawn_id then @@ -590,6 +736,7 @@ Event.add(defines.events.on_player_created,function(event) end end) +--- When a chart tag is removed or edited make sure it is not one that belongs to a warp local function maintain_tag(event) if not event.player_index then return end local tag = event.tag @@ -608,6 +755,4 @@ local function maintain_tag(event) end Event.add(defines.events.on_chart_tag_modified,maintain_tag) -Event.add(defines.events.on_chart_tag_removed,maintain_tag) - -return warp_list \ No newline at end of file +Event.add(defines.events.on_chart_tag_removed,maintain_tag) \ No newline at end of file From ebf08fa989ab4f1d5bc5acbb0da05b295ca6dbfa Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 25 Oct 2019 23:42:35 +0100 Subject: [PATCH 07/81] Updated science info --- config/_file_loader.lua | 2 +- docs/addons/Advanced-Start.html | 2 +- docs/addons/Chat-Popups.html | 2 +- docs/addons/Chat-Reply.html | 2 +- docs/addons/Compilatron.html | 2 +- docs/addons/Damage-Popups.html | 2 +- docs/addons/Death-Logger.html | 2 +- docs/addons/Discord-Alerts.html | 2 +- docs/addons/Player-Colours.html | 2 +- docs/addons/Pollution-Grading.html | 2 +- docs/addons/Scorched-Earth.html | 2 +- docs/addons/Spawn-Area.html | 2 +- docs/commands/Admin-Chat.html | 2 +- docs/commands/Bonus.html | 2 +- docs/commands/Cheat-Mode.html | 2 +- docs/commands/Clear-Inventory.html | 2 +- docs/commands/Debug.html | 2 +- docs/commands/Find.html | 2 +- docs/commands/Help.html | 2 +- docs/commands/Home.html | 2 +- docs/commands/Interface.html | 2 +- docs/commands/Jail.html | 2 +- docs/commands/Kill.html | 2 +- docs/commands/Me.html | 2 +- docs/commands/Rainbow.html | 2 +- docs/commands/Repair.html | 2 +- docs/commands/Reports.html | 2 +- docs/commands/Roles.html | 2 +- docs/commands/Spawn.html | 2 +- docs/commands/Tag.html | 2 +- docs/commands/Teleport.html | 2 +- docs/commands/Warnings.html | 2 +- docs/configs/Advanced-Start.html | 2 +- docs/configs/Bonuses.html | 2 +- docs/configs/Chat-Reply.html | 2 +- docs/configs/Commands-Auth-Admin.html | 2 +- docs/configs/Commands-Auth-Roles.html | 2 +- .../Commands-Auth-Runtime-Disable.html | 2 +- docs/configs/Commands-Parse-Roles.html | 2 +- docs/configs/Commands-Parse.html | 2 +- docs/configs/Compilatron.html | 2 +- docs/configs/Death-Logger.html | 2 +- docs/configs/Discord-Alerts.html | 2 +- docs/configs/File-Loader.html | 2 +- docs/configs/Permission-Groups.html | 2 +- docs/configs/Player-List.html | 2 +- docs/configs/Pollution-Grading.html | 2 +- docs/configs/Popup-Messages.html | 2 +- docs/configs/Preset-Player-Colours.html | 2 +- docs/configs/Repair.html | 2 +- docs/configs/Rockets.html | 2 +- docs/configs/Roles.html | 2 +- docs/configs/Science.html | 2 +- docs/configs/Scorched-Earth.html | 2 +- docs/configs/Spawn-Area.html | 2 +- docs/configs/Tasks.html | 2 +- docs/configs/Warnings.html | 2 +- docs/configs/Warps.html | 4 +- docs/control/Jail.html | 2 +- docs/control/Production.html | 2 +- docs/control/Reports.html | 2 +- docs/control/Rockets.html | 2 +- docs/control/Tasks.html | 2 +- docs/control/Warnings.html | 2 +- docs/control/Warps.html | 2 +- docs/core/Commands.html | 2 +- docs/core/Common-Library.html | 2 +- docs/core/Gui.html | 2 +- docs/core/Permissions-Groups.html | 2 +- docs/core/Roles.html | 2 +- docs/core/Store.html | 2 +- docs/core/Sudo.html | 2 +- docs/guis/Player-List.html | 2 +- docs/guis/Rocket-Info.html | 2 +- docs/guis/Science-Info.html | 133 +++- docs/guis/Task-List.html | 2 +- docs/guis/Warps-List.html | 2 +- docs/index.html | 2 +- docs/modules/control.html | 2 +- .../utils.alien_evolution_progress.html | 2 +- docs/modules/utils.core.html | 2 +- docs/modules/utils.debug.html | 2 +- docs/modules/utils.dump_env.html | 2 +- docs/modules/utils.event.html | 2 +- docs/modules/utils.event_core.html | 2 +- docs/modules/utils.math.html | 2 +- docs/modules/utils.recipe_locker.html | 2 +- docs/modules/utils.state_machine.html | 2 +- docs/modules/utils.table.html | 2 +- docs/modules/utils.task.html | 2 +- docs/modules/utils.timestamp.html | 2 +- docs/topics/license.html | 2 +- docs/topics/readme.md.html | 2 +- modules/gui/science-info.lua | 630 +++++++++++------- 94 files changed, 605 insertions(+), 344 deletions(-) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 7629b905..fa73ff34 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -40,7 +40,7 @@ return { 'modules.addons.chat-reply', -- GUI --'modules.gui.rocket-info', - --'modules.gui.science-info', + 'modules.gui.science-info', 'modules.gui.warp-list', 'modules.gui.task-list', --'modules.gui.player-list', diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index a94550d3..e06593f6 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -348,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index 5104f56d..7cb0c9b2 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index 12b2d4b7..6c368f68 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index eda52288..135ff83a 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index a9885689..df0b8737 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index 20304e86..4f94aece 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index b5db145a..12bccc87 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -460,7 +460,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index b6c03a49..0682c770 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index 8a822e46..8ecf95bf 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index 1beb5873..84ea1706 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 0545406e..9cd696ab 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 2cd5e62f..7967ea77 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index 7ed81faf..f0b1fc7b 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -500,7 +500,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index 9fe4825c..680b91e8 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -361,7 +361,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index d14c747d..7026f517 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index c774d4d6..6667e00b 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -365,7 +365,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index 5eae53a7..e95e5332 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index b69015ea..deb9aa2a 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index 4f5e97b4..e9b13bfd 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -458,7 +458,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index 5f0aa397..89212f3b 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 15d03b28..2c670b45 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -611,7 +611,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index d857f4de..f6e57348 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index a1e124e2..59c4534a 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index d81a5601..6c90fe3f 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index 89d221c1..004ec4bd 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -321,7 +321,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index 68d1dbac..2f71921c 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index e76ebc00..ba0318c7 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -557,7 +557,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index ae86a1c8..fda9f645 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index 1308a173..9cf7157a 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -443,7 +443,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index 3766b23a..e9131888 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -484,7 +484,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index f6b81295..ac587916 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -569,7 +569,7 @@ generated by LDoc diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index edadff82..75ce3491 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -506,7 +506,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index 93bd8e14..cc4d5595 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index 0dda65b9..d7ae726a 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -485,7 +485,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index 82cc7f4b..4a48d6da 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -294,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index f4b77ef8..ed1c5b7f 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index d72f5edf..e72d1a81 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index 00353bdc..f9d62d80 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index 5cd6e37d..d1d21e74 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -338,7 +338,7 @@ see ./expcore/commands.lua for more details

    generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index c1e53996..7dc0e1b5 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index e345fe69..ab9a69db 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index 27950dfa..40ee9ed3 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 9f00aa0c..11aeb9af 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -240,7 +240,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index c794811b..6329eb61 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -295,7 +295,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index ae73091b..2d23727d 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -812,7 +812,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index 6251d78c..2c6dc312 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index c39118c6..bf97ecf9 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index af464cc2..3fd3eca5 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -324,7 +324,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index 858ae123..82dcaa12 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index d8c76b79..a318f0cd 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -834,7 +834,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index f08ad41d..c324a6ac 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -292,7 +292,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index 0abe99c3..f5dca812 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index 5c8300dc..f011372b 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index 46f1ca96..fac7d663 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -744,7 +744,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index 4b21194e..4e84ef99 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index e1fb3569..09b6a980 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -355,7 +355,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index 723c7258..0353eba6 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -311,7 +311,7 @@

    -

    the amount of smoothing applied to updates to the cooldown timer, higher is better

    +

    the amount of smoothing applied to updates to the cooldown timer, higher is better, max is 60

    @@ -774,7 +774,7 @@ generated by LDoc
    diff --git a/docs/control/Jail.html b/docs/control/Jail.html index 65aeb8d0..4f02fcb1 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -1208,7 +1208,7 @@ generated by LDoc diff --git a/docs/control/Production.html b/docs/control/Production.html index 252850bf..301380da 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -1329,7 +1329,7 @@ generated by LDoc diff --git a/docs/control/Reports.html b/docs/control/Reports.html index c722290a..349a872c 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -1110,7 +1110,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index b53870c6..2f5efd39 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -984,7 +984,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index 64a3b413..440f1c35 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -998,7 +998,7 @@ Tasks.update_task(task_id,'We need more iron!',game. generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index 31e9150f..32c13b69 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -1465,7 +1465,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index 6580b84a..5a52b7df 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -1563,7 +1563,7 @@ Warps.make_warp_tag(warp_id) generated by LDoc diff --git a/docs/core/Commands.html b/docs/core/Commands.html index 3a2e7a33..26e2e30e 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -1972,7 +1972,7 @@ generated by LDoc diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index dab10ae9..6b2cd701 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -2746,7 +2746,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Gui.html b/docs/core/Gui.html index 21d1c537..72fc7784 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -2851,7 +2851,7 @@ Gui.element{ generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index bf67317a..dc36167e 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -1432,7 +1432,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index 3beabbe4..25ceecf4 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -3152,7 +3152,7 @@ generated by LDoc diff --git a/docs/core/Store.html b/docs/core/Store.html index 5cf287d0..fd876dbc 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -1481,7 +1481,7 @@ Store.set(player_scores,game.player,10) generated by LDoc diff --git a/docs/core/Sudo.html b/docs/core/Sudo.html index 479ac70d..27c2542b 100644 --- a/docs/core/Sudo.html +++ b/docs/core/Sudo.html @@ -544,7 +544,7 @@ generated by LDoc diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index be347756..0dbdaafd 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -626,7 +626,7 @@ generated by LDoc diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index 2c0e4c87..3de18001 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -629,7 +629,7 @@ generated by LDoc diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 3ba61f51..5d2fbcd2 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -247,6 +247,9 @@ expcore.gui + expcore.gui + + utils.event @@ -267,8 +270,20 @@ - science_info - Registers the science info + production_label + Data label that contains the value and the surfix + + + science_pack_base + Adds 4 elements that show the data for a science pack + + + task_list_container + Main task list container for the left flow + + + task_list_toggle + Button on the top flow used to toggle the task list container @@ -297,6 +312,31 @@ + + + + + + +
    +
    +
    +
    + # + expcore.gui +
    +
    +
    +
    + + + + + + + + + @@ -410,14 +450,95 @@
    - # - science_info + # + production_label
    -

    Registers the science info

    +

    Data label that contains the value and the surfix

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + science_pack_base +
    +
    +
    +
    + +

    Adds 4 elements that show the data for a science pack

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_list_container +
    +
    +
    +
    + +

    Main task list container for the left flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + task_list_toggle +
    +
    +
    +
    + +

    Button on the top flow used to toggle the task list container

    @@ -449,7 +570,7 @@ generated by LDoc
    diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index 6136165e..8e546493 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -756,7 +756,7 @@ generated by LDoc diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index db64af56..2f4ac049 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -961,7 +961,7 @@ generated by LDoc diff --git a/docs/index.html b/docs/index.html index 6154fead..2b553d42 100644 --- a/docs/index.html +++ b/docs/index.html @@ -511,7 +511,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index a712091a..4fc84050 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -351,7 +351,7 @@ generated by LDoc diff --git a/docs/modules/utils.alien_evolution_progress.html b/docs/modules/utils.alien_evolution_progress.html index 3ffd68e8..fdb538e2 100644 --- a/docs/modules/utils.alien_evolution_progress.html +++ b/docs/modules/utils.alien_evolution_progress.html @@ -419,7 +419,7 @@ fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on generated by LDoc diff --git a/docs/modules/utils.core.html b/docs/modules/utils.core.html index 48b74c3f..c94a85ca 100644 --- a/docs/modules/utils.core.html +++ b/docs/modules/utils.core.html @@ -1164,7 +1164,7 @@ generated by LDoc diff --git a/docs/modules/utils.debug.html b/docs/modules/utils.debug.html index b34baf22..d9fc0fa5 100644 --- a/docs/modules/utils.debug.html +++ b/docs/modules/utils.debug.html @@ -654,7 +654,7 @@ generated by LDoc diff --git a/docs/modules/utils.dump_env.html b/docs/modules/utils.dump_env.html index 42ee92fc..1a275d2f 100644 --- a/docs/modules/utils.dump_env.html +++ b/docs/modules/utils.dump_env.html @@ -323,7 +323,7 @@ generated by LDoc diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index f851a4f8..0613535f 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -1292,7 +1292,7 @@ generated by LDoc diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index aed7f3cf..4714e6ed 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -434,7 +434,7 @@ generated by LDoc diff --git a/docs/modules/utils.math.html b/docs/modules/utils.math.html index f72252fd..24562934 100644 --- a/docs/modules/utils.math.html +++ b/docs/modules/utils.math.html @@ -353,7 +353,7 @@ generated by LDoc diff --git a/docs/modules/utils.recipe_locker.html b/docs/modules/utils.recipe_locker.html index 20e6ef12..11b985c3 100644 --- a/docs/modules/utils.recipe_locker.html +++ b/docs/modules/utils.recipe_locker.html @@ -441,7 +441,7 @@ generated by LDoc diff --git a/docs/modules/utils.state_machine.html b/docs/modules/utils.state_machine.html index 9fe3a7ae..0166e736 100644 --- a/docs/modules/utils.state_machine.html +++ b/docs/modules/utils.state_machine.html @@ -752,7 +752,7 @@ generated by LDoc diff --git a/docs/modules/utils.table.html b/docs/modules/utils.table.html index d7c02aa1..f5c0e283 100644 --- a/docs/modules/utils.table.html +++ b/docs/modules/utils.table.html @@ -1418,7 +1418,7 @@ generated by LDoc diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index dda2c43f..4d025c24 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -651,7 +651,7 @@ generated by LDoc diff --git a/docs/modules/utils.timestamp.html b/docs/modules/utils.timestamp.html index 98b6d7f3..ffcfd375 100644 --- a/docs/modules/utils.timestamp.html +++ b/docs/modules/utils.timestamp.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index 2d42a575..6d78546c 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -789,7 +789,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index 4284e0e5..488a3235 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -338,7 +338,7 @@ Please report these errors to [the issues page](issues). generated by LDoc diff --git a/modules/gui/science-info.lua b/modules/gui/science-info.lua index 9ecce6e2..a3d74b33 100644 --- a/modules/gui/science-info.lua +++ b/modules/gui/science-info.lua @@ -5,6 +5,7 @@ ]] local Gui = require 'expcore.gui' --- @dep expcore.gui +local Roles = require 'expcore.roles' --- @dep expcore.gui local Event = require 'utils.event' --- @dep utils.event local format_time = ext_require('expcore.common','format_time') --- @dep expcore.common local config = require 'config.science' --- @dep config.science @@ -13,275 +14,414 @@ local Production = require 'modules.control.production' --- @dep modules.control local null_time_short = {'science-info.eta-time',format_time(0,{hours=true,minutes=true,seconds=true,time=true,null=true})} local null_time_long = format_time(0,{hours=true,minutes=true,seconds=true,long=true,null=true}) ---[[ Generates the main structure for the gui - element - > container - >> header - >> scroll - >>> non_made - >>> table - >> footer (when eta is enabled) - >>> eta-label - >>> eta - >>>> label -]] -local function generate_container(element) - Gui.set_padding(element,1,2,2,2) - element.style.minimal_width = 200 +--- Data label that contains the value and the surfix +-- @element production_label +local production_label = +Gui.element(function(_,parent,production_label_data) + local name = production_label_data.name + local tooltip = production_label_data.tooltip + local color = production_label_data.color - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' + -- Add an alignment for the number + local alignment = Gui.alignment(parent,nil,nil,name) + + -- Add the main value label + local element = + alignment.add{ + name = 'label', + type = 'label', + caption = production_label_data.caption, + tooltip = tooltip } - Gui.set_padding(container) - -- main header for the gui - Gui.create_header( + -- Change the style + element.style.font_color = color + + -- Add the surfix label + local surfix_element = + parent.add{ + name = 'surfix-'..name, + type = 'label', + caption = {'science-info.unit',production_label_data.surfix}, + tooltip = tooltip + } + + -- Change the style + surfix_element.style.font_color = color + + -- Return the value label + return element +end) + +-- Get the data that is used with the production label +local function get_production_label_data(name,tooltip,value,secondary) + local data_colour = Production.get_color(config.color_clamp, value, secondary) + local surfix,caption = Production.format_number(value) + + return { + name = name, + caption = caption, + surfix = surfix, + tooltip = tooltip, + color = data_colour + } +end + +-- Updates a prodution label to match the current data +local function update_production_label(parent,production_label_data) + local name = production_label_data.name + local tooltip = production_label_data.tooltip + local color = production_label_data.color + + -- Update the production label + local production_label_element = parent[name] and parent[name].label or production_label(parent,production_label_data) + production_label_element.caption = production_label_data.caption + production_label_element.tooltip = production_label_data.tooltip + production_label_element.style.font_color = color + + -- Update the surfix label + local surfix_element = parent['surfix-'..name] + surfix_element.caption = {'science-info.unit',production_label_data.surfix} + surfix_element.tooltip = tooltip + surfix_element.style.font_color = color + +end + +--- Adds 4 elements that show the data for a science pack +-- @element science_pack_base +local science_pack_base = +Gui.element(function(_,parent,science_pack_data) + local science_pack = science_pack_data.science_pack + + -- Draw the icon for the science pack + local icon_style = science_pack_data.icon_style + local pack_icon = + parent.add{ + name = 'icon-'..science_pack, + type = 'sprite-button', + sprite = 'item/'..science_pack, + tooltip = {'item-name.'..science_pack}, + style = icon_style + } + + -- Change the style of the icon + local pack_icon_style = pack_icon.style + pack_icon_style.height = 55 + if icon_style == 'quick_bar_slot_button' then + pack_icon_style.padding = {0,-2} + pack_icon_style.width = 36 + end + + -- Draw the delta flow + local delta_flow = + parent.add{ + name = 'delta-'..science_pack, + type = 'frame', + style = 'bordered_frame' + } + + -- Change the style of the delta flow + delta_flow.style.padding = {0,3} + + -- Draw the delta flow table + local delta_table = + delta_flow.add{ + name = 'table', + type = 'table', + column_count = 2 + } + + -- Change the style of the delta flow table + delta_table.style.padding = 0 + + -- Draw the production labels + update_production_label(delta_table,science_pack_data.positive) + update_production_label(delta_table,science_pack_data.negative) + update_production_label(parent,science_pack_data.net) + + -- Return the pack icon + return pack_icon +end) + +local function get_science_pack_data(player,science_pack) + local force = player.force + + -- Check that some packs have been made + local total = Production.get_production_total(force, science_pack) + local minute = Production.get_production(force, science_pack, defines.flow_precision_index.one_minute) + if total.made == 0 then + return + end + + -- Get the icon style + local icon_style = 'quick_bar_slot_button' + local flux = Production.get_fluctuations(force, science_pack, defines.flow_precision_index.one_minute) + if minute.net > 0 and flux.net > -config.color_flux/2 then + icon_style = 'green_slot_button' + elseif flux.net < -config.color_flux then + icon_style = 'red_slot_button' + elseif minute.made > 0 then + icon_style = 'selected_slot_button' + end + + -- Return the pack data + return { + science_pack = science_pack, + icon_style = icon_style, + positive = get_production_label_data( + 'pos-'..science_pack, + {'science-info.pos-tooltip', total.made}, + minute.made + ), + negative = get_production_label_data( + 'neg-'..science_pack, + {'science-info.neg-tooltip', total.used}, + -minute.used + ), + net = get_production_label_data( + 'net-'..science_pack, + {'science-info.net-tooltip', total.net}, + minute.net, + minute.made+minute.used + ) + } + +end + +local function update_science_pack(pack_table,science_pack_data) + if not science_pack_data then return end + local science_pack = science_pack_data.science_pack + pack_table.parent.non_made.visible = false + + -- Update the icon + local pack_icon = pack_table['icon-'..science_pack] or science_pack_base(pack_table,science_pack_data) + local icon_style = science_pack_data.icon_style + pack_icon.style = icon_style + + local pack_icon_style = pack_icon.style + pack_icon_style.height = 55 + if icon_style == 'quick_bar_slot_button' then + pack_icon_style.padding = {0,-2} + pack_icon_style.width = 36 + end + + -- Update the production labels + local delta_table = pack_table['delta-'..science_pack].table + update_production_label(delta_table,science_pack_data.positive) + update_production_label(delta_table,science_pack_data.negative) + update_production_label(pack_table,science_pack_data.net) + +end + +--- Gets the data that is used with the eta label +local function get_eta_label_data(player) + local force = player.force + + -- If there is no current research then return no research + local research = force.current_research + if not research then + return { research = false } + end + + local progress = force.research_progress + local remaining = research.research_unit_count*(1-progress) + local limit + + -- Check for the limiting science pack + for _,ingredient in pairs(research.research_unit_ingredients) do + local pack_name = ingredient.name + local required = ingredient.amount * remaining + local time = Production.get_consumsion_eta(force, pack_name, defines.flow_precision_index.one_minute, required) + if not limit or limit < time then + limit = time + end + end + + -- Return the caption and tooltip + return limit and limit > 0 and { + research = true, + caption = format_time(limit,{hours=true,minutes=true,seconds=true,time=true}), + tooltip = format_time(limit,{hours=true,minutes=true,seconds=true,long=true}) + } or { research = false } + +end + +-- Updates the eta label +local function update_eta_label(element,eta_label_data) + -- If no research selected show null + if not eta_label_data.research then + element.caption = null_time_short + element.tooltip = null_time_long + return + end + + -- Update the element + element.caption = {'science-info.eta-time',eta_label_data.caption} + element.tooltip = eta_label_data.tooltip +end + +--- Main task list container for the left flow +-- @element task_list_container +local science_info_container = +Gui.element(function(event_trigger,parent) + local player = Gui.get_player_from_element(parent) + + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' + } + + -- Set the frame style + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 + + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } + + -- Set the container style + local style = container.style + style.vertically_stretchable = false + + -- Draw the header + Gui.header( container, {'science-info.main-caption'}, {'science-info.main-tooltip'} ) - -- table that stores all the data - local flow_table = Gui.create_scroll_table(container,4,185) + -- Draw the scroll table for the tasks + local scroll_table = Gui.scroll_table(container,185,4) - -- message to say that you have not made any packs yet - local non_made = - flow_table.parent.add{ - name='non_made', - type='label', - caption={'science-info.no-packs'} + -- Draw the no packs label + local no_packs_label = + scroll_table.parent.add{ + name = 'non_made', + type = 'label', + caption = {'science-info.no-packs'} } - non_made.style.width = 200 - non_made.style.single_line = false - local eta + -- Change the style of the no packs label + local no_packs_style = no_packs_label.style + no_packs_style.padding = {2,4} + no_packs_style.single_line = false + no_packs_style.width = 200 + + -- Add the footer and eta if config.show_eta then - -- footer used to store the eta - local footer = - container.add{ - name='footer', - type='frame', - style='subheader_frame' - } - Gui.set_padding(footer,2,2,4,4) - footer.style.horizontally_stretchable = true + -- Draw the footer + local footer = Gui.header( + container, + {'science-info.eta-caption'}, + {'science-info.eta-tooltip'}, + true, + 'footer' + ) - -- label for the footer + -- Set the style + footer.parent.style = 'subheader_frame' + local footer_style = footer.parent.style + footer_style.padding = {2,4} + footer_style.use_header_filler = false + footer_style.horizontally_stretchable = true + + -- Draw the eta label + local eta_label = footer.add{ - name='eta-label', - type='label', - caption={'science-info.eta-caption'}, - tooltip={'science-info.eta-tooltip'}, - style='heading_1_label' + name = 'label', + type = 'label', + caption = null_time_short, + tooltip = null_time_long, + style = 'heading_1_label' } - -- data for the footer - local right_align = Gui.create_alignment(footer,'eta') - eta = - right_align.add{ - name='label', - type='label', - caption=null_time_short, - tooltip=null_time_long, - style='heading_1_label' - } + -- Update the eta + update_eta_label(eta_label,get_eta_label_data(player)) + end - return flow_table, eta -end - ---[[ Adds two labels where one is right aligned and the other is a unit - element - > "name" - >> label - > spm-"name" -]] -local function add_data_label(element,name,value,secondary,tooltip) - local data_colour = Production.get_color(config.color_clamp, value, secondary) - local surfix,caption = Production.format_number(value) - - if element[name] then - local data = element[name].label - data.caption = caption - data.tooltip = tooltip - data.style.font_color = data_colour - local label = element['spm-'..name] - label.caption = {'science-info.unit',surfix} - label.tooltip = tooltip - label.style.font_color = data_colour - - else - -- right aligned number - local right_align = Gui.create_alignment(element,name) - local data = - right_align.add{ - name='label', - type='label', - caption=caption, - tooltip=tooltip - } - data.style.font_color = data_colour - - -- adds the unit onto the end - local label = - element.add{ - name='spm-'..name, - type='label', - caption={'science-info.unit',surfix}, - tooltip=tooltip - } - label.style.font_color = data_colour - end -end - ---[[ Adds a science pack to the list - element - > icon-"science_pack" - > delta-"science_pack" - >> table - >>> pos-"science_pack" (add_data_label) - >>> neg-"science_pack" (add_data_label) - > net-"science_pack" (add_data_label) -]] -local function generate_science_pack(player,element,science_pack) - local total = Production.get_production_total(player.force, science_pack) - local minute = Production.get_production(player.force, science_pack, defines.flow_precision_index.one_minute) - if total.made > 0 then - element.parent.non_made.visible = false - - local icon_style = 'quick_bar_slot_button' - local flux = Production.get_fluctuations(player.force, science_pack, defines.flow_precision_index.one_minute) - if flux.net > -config.color_flux/2 then - icon_style = 'green_slot_button' - elseif flux.net < -config.color_flux then - icon_style = 'red_slot_button' - elseif minute.made > 0 then - icon_style = 'selected_slot_button' - end - - local icon = element['icon-'..science_pack] - - if icon then - icon.style = icon_style - icon.style.height = 55 - if icon_style == 'quick_bar_slot_button' then - icon.style.width = 36 - Gui.set_padding(icon,0,0,-2,-2) - end - - else - icon = - element.add{ - name='icon-'..science_pack, - type='sprite-button', - sprite='item/'..science_pack, - tooltip={'item-name.'..science_pack}, - style=icon_style - } - icon.style.height = 55 - if icon_style == 'quick_bar_slot_button' then - icon.style.width = 36 - Gui.set_padding(icon,0,0,-2,-2) - end - - end - - local delta = element['delta-'..science_pack] - - if not delta then - delta = - element.add{ - name='delta-'..science_pack, - type='frame', - style='bordered_frame' - } - Gui.set_padding(delta,0,0,3,3) - - local delta_table = - delta.add{ - name='table', - type='table', - column_count=2 - } - Gui.set_padding(delta_table) - end - - add_data_label(delta.table,'pos-'..science_pack,minute.made,nil,{'science-info.pos-tooltip',total.made}) - add_data_label(delta.table,'neg-'..science_pack,-minute.used,nil,{'science-info.neg-tooltip',total.used}) - add_data_label(element,'net-'..science_pack,minute.net,minute.made+minute.used,{'science-info.net-tooltip',total.net}) - end -end - ---- Updates the eta label that was created with generate_container -local function update_eta(player,element) - if not config.show_eta then return end - local force = player.force - local research = force.current_research - if not research then - element.caption = null_time_short - element.tooltip = null_time_long - - else - local progress = force.research_progress - local remaining = research.research_unit_count*(1-progress) - local limit - - local stats = player.force.item_production_statistics - for _,ingredient in pairs(research.research_unit_ingredients) do - local pack_name = ingredient.name - local required = ingredient.amount * remaining - local time = Production.get_consumsion_eta(force, pack_name, defines.flow_precision_index.one_minute, required) - if not limit or limit < time then - limit = time - end - end - - if not limit or limit == -1 then - element.caption = null_time_short - element.tooltip = null_time_long - - else - element.caption = {'science-info.eta-time',format_time(limit,{hours=true,minutes=true,seconds=true,time=true})} - element.tooltip = format_time(limit,{hours=true,minutes=true,seconds=true,long=true}) - - end - end -end - ---- Registers the science info --- @element science_info -local science_info = -Gui.new_left_frame('gui/science-info') -:set_sprites('entity/lab') -:set_direction('vertical') -:set_tooltip{'science-info.main-tooltip'} -:on_creation(function(player,element) - local table, eta = generate_container(element) - + -- Add packs which have been made for _,science_pack in ipairs(config) do - generate_science_pack(player,table,science_pack) + update_science_pack(scroll_table,get_science_pack_data(player,science_pack)) end - update_eta(player,eta) + -- Return the exteral container + return frame end) -:on_update(function(player,element) - local container = element.container - local table = container.scroll.table - local eta = container.footer.eta.label +:add_to_left_flow() - for _,science_pack in ipairs(config) do - generate_science_pack(player,table,science_pack) - end - - update_eta(player,eta) +--- Button on the top flow used to toggle the task list container +-- @element task_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'entity/lab', + tooltip = {'science-info.main-tooltip'}, + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/science-info') +end) +:on_click(function(player,_,_) + Gui.toggle_left_element(player, science_info_container) end) --- Updates the gui every 1 second -Event.on_nth_tick(60,science_info 'update_all') +Event.on_nth_tick(60,function() + local force_pack_data = {} + local force_eta_data = {} + for _,player in pairs(game.connected_players) do + local force_name = player.force.name + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[science_info_container.name] + local container = frame.container -return science_info \ No newline at end of file + -- Update the science packs + local scroll_table = container.scroll.table + local pack_data = force_pack_data[force_name] + if not pack_data then + -- No data in chache so it needs to be generated + pack_data = {} + force_pack_data[force_name] = pack_data + for _,science_pack in ipairs(config) do + local next_data = get_science_pack_data(player,science_pack) + pack_data[science_pack] = next_data + update_science_pack(scroll_table,next_data) + end + + else + -- Data found in chache is no need to generate it + for _,next_data in ipairs(pack_data) do + update_science_pack(scroll_table,next_data) + end + + end + + -- Update the eta times + if not config.show_eta then return end + local eta_label = container.footer.alignment.label + local eta_data = force_eta_data[force_name] + if not eta_data then + -- No data in chache so it needs to be generated + eta_data = get_eta_label_data(player) + force_eta_data[force_name] = eta_data + update_eta_label(eta_label,eta_data) + + else + -- Data found in chache is no need to generate it + update_eta_label(eta_label,eta_data) + + end + + end +end) \ No newline at end of file From ecf99b11420d4a28317a9dce44d73c3325c15faf Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 11 Jan 2020 01:32:16 +0000 Subject: [PATCH 08/81] Rocket Info Gui --- README.md | 2 +- config/_file_loader.lua | 2 +- locale/en/gui.cfg | 2 + modules/gui/rocket-info.lua | 981 ++++++++++++++++++++---------------- 4 files changed, 554 insertions(+), 433 deletions(-) diff --git a/README.md b/README.md index affbc44a..c1ab73b8 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Please report these errors to [the issues page](issues). ## Contributing -All are welcome to make pull requests and issues for this scenario, if you are in any doubt, please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. All our docs can be found [here][docs]. Please keep in mind while making code changes: +All are welcome to make pull requests and issues for this scenario, if you are in any doubt, please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. To find out what we already have please read our [docs]. Please keep in mind while making code changes: * New features should have the branch names: `feature/feature-name` * New features are merged into `dev` after it has been completed, this can be done through a pull request. diff --git a/config/_file_loader.lua b/config/_file_loader.lua index fa73ff34..474cc842 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -39,7 +39,7 @@ return { 'modules.addons.discord-alerts', 'modules.addons.chat-reply', -- GUI - --'modules.gui.rocket-info', + 'modules.gui.rocket-info', 'modules.gui.science-info', 'modules.gui.warp-list', 'modules.gui.task-list', diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 332d2f42..440f485d 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -46,6 +46,8 @@ data-caption-avg-launch-n=Average Time __1__ data-tooltip-avg-launch-n=The average amount of time taken to launch the last __1__ rockets data-caption-milestone-n=Milestone __1__ data-tooltip-milestone-n=Time taken to each __1__ rockets +data-caption-milestone-next=N/A +data-tooltip-milestone-next=Not yet achieved progress-x-pos=X __1__ progress-y-pos=Y __1__ progress-label-tooltip=View on map diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index fd384627..69c2d9d9 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -12,8 +12,15 @@ local format_time = ext_require('expcore.common','format_time') --- @dep expcore local Colors = require 'resources.color_presets' --- @dep resources.color_presets local Rockets = require 'modules.control.rockets' --- @dep modules.control.rockets ---- Gets if a player is allowed to use the action buttons -local function player_allowed(player,action) +local time_formats = { + caption = function(value) return format_time(value, {minutes=true, seconds=true}) end, + caption_hours = function(value) return format_time(value) end, + tooltip = function(value) return format_time(value, {minutes=true, seconds=true, long=true}) end, + tooltip_hours = function(value) return format_time(value, {hours=true, minutes=true, seconds=true, long=true}) end +} + +--- Check if a player is allowed to use certain interactions +local function check_player_permissions(player,action) if not config.progress['allow_'..action] then return false end @@ -29,31 +36,191 @@ local function player_allowed(player,action) return true end ---- Used on the name label to allow zoom to map --- @element zoom_to_map -local zoom_to_map_name = Gui.uid_name() -Gui.on_click(zoom_to_map_name,function(event) - local rocket_silo_name = event.element.parent.caption - local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) - event.player.zoom_to_world(rocket_silo.position,2) +--- Data label which contains a name and a value label pair +-- @element data_label +local data_label = +Gui.element(function(_,parent,label_data) + local data_name = label_data.name + local data_subname = label_data.subname + local data_fullname = data_subname and data_name..data_subname or data_name + + -- Add the name label + parent.add{ + type = 'label', + name = data_fullname..'-label', + caption = {'rocket-info.data-caption-'..data_name,data_subname}, + tooltip = {'rocket-info.data-tooltip-'..data_name,data_subname} + } + + --- Right aligned label to store the data + local alignment = Gui.alignment(parent,nil,nil,data_fullname) + local element = + alignment.add{ + type = 'label', + name = 'label', + caption = label_data.value, + tooltip = label_data.tooltip + } + + return element end) ---- Used to launch the rocket, when it is ready +local function update_data_labels(parent,data_label_data) + for _, label_data in ipairs(data_label_data) do + local data_name = label_data.subname and label_data.name..label_data.subname or label_data.name + if not parent[data_name] then + data_label(parent,label_data) + else + local data_label_element = parent[data_name].label + data_label_element.tooltip = label_data.tooltip + data_label_element.caption = label_data.value + end + end +end + +--- Gets the label data for all the different stats +local function get_stats_data(force_name) + local force_rockets = Rockets.get_rocket_count(force_name) + local stats = Rockets.get_stats(force_name) + local stats_data = {} + + -- Format the first launch data + if config.stats.show_first_rocket then + local value = stats.first_launch or 0 + table.insert(stats_data,{ + name = 'first-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format the last launch data + if config.stats.show_last_rocket then + local value = stats.last_launch or 0 + table.insert(stats_data,{ + name = 'last-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format fastest launch data + if config.stats.show_fastest_rocket then + local value = stats.fastest_launch or 0 + table.insert(stats_data,{ + name = 'fastest-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format total rocket data + if config.stats.show_total_rockets then + local total_rockets = Rockets.get_game_rocket_count() + total_rockets = total_rockets == 0 and 1 or total_rockets + local percentage = math.round(force_rockets/total_rockets,3)*100 + table.insert(stats_data,{ + name = 'total-rockets', + value = force_rockets, + tooltip = {'rocket-info.value-tooltip-total-rockets',percentage} + }) + end + + -- Format game avg data + if config.stats.show_game_avg then + local avg = force_rockets > 0 and math.floor(game.tick/force_rockets) or 0 + table.insert(stats_data,{ + name = 'avg-launch', + value = time_formats.caption(avg), + tooltip = time_formats.tooltip(avg) + }) + end + + -- Format rolling avg data + for _,avg_over in pairs(config.stats.rolling_avg) do + local avg = Rockets.get_rolling_average(force_name,avg_over) + table.insert(stats_data,{ + name = 'avg-launch-n', + subname = avg_over, + value = time_formats.caption(avg), + tooltip = time_formats.tooltip(avg) + }) + end + + -- Return formated data + return stats_data +end + +--- Gets the label data for the milestones +local function get_milestone_data(force_name) + local force_rockets = Rockets.get_rocket_count(force_name) + local milestone_data = {} + + for _,milestone in ipairs(config.milestones) do + if milestone <= force_rockets then + local time = Rockets.get_rocket_time(force_name,milestone) + table.insert(milestone_data,{ + name = 'milestone-n', + subname = milestone, + value = time_formats.caption_hours(time), + tooltip = time_formats.tooltip_hours(time) + }) + else + table.insert(milestone_data,{ + name = 'milestone-n', + subname = milestone, + value = {'rocket-info.data-caption-milestone-next'}, + tooltip = {'rocket-info.data-tooltip-milestone-next'} + }) + break + end + end + + return milestone_data +end + +--- Button to toggle the auto launch on a rocket silo +-- @elemeent toggle_launch +local toggle_launch = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/play', + tooltip = {'rocket-info.toggle-rocket-tooltip'} +} +:style{ + padding = -2, + width = 16, + height = 16 +} +:on_click(function(player,element,_) + local rocket_silo_name = element.parent.name:sub(8) + local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) + if rocket_silo.auto_launch then + element.sprite = 'utility/play' + element.tooltip = {'rocket-info.toggle-rocket-tooltip'} + rocket_silo.auto_launch = false + else + element.sprite = 'utility/stop' + element.tooltip = {'rocket-info.toggle-rocket-tooltip-disabled'} + rocket_silo.auto_launch = true + end +end) + +--- Button to remotely launch a rocket from a silo -- @element launch_rocket local launch_rocket = -Gui.new_button() -:set_sprites('utility/center') -:set_tooltip{'rocket-info.launch-tooltip'} -:set_embedded_flow(function(element,rocket_silo_name) - return 'launch-'..rocket_silo_name -end) -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.width = 16 - style.height = 16 -end) -:on_click(function(player,element) - local rocket_silo_name = element.parent.name:sub(8) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/center', + tooltip = {'rocket-info.launch-tooltip'} +} +:style{ + padding = -2, + width = 16, + height = 16 +} +:on_click(function(player,element,_) + local rocket_silo_name = element.parent.name:sub(8) local silo_data = Rockets.get_silo_data_by_name(rocket_silo_name) if silo_data.entity.launch_rocket() then silo_data.awaiting_reset = true @@ -66,457 +233,409 @@ end) end end) ---- Used to toggle the auto launch on a rocket --- @element toggle_rocket -local toggle_rocket = -Gui.new_button() -:set_sprites('utility/play') -:set_tooltip{'rocket-info.toggle-rocket-tooltip'} -:set_embedded_flow(function(element,rocket_silo_name) - return 'toggle-'..rocket_silo_name +--- XY cords that allow zoom to map when pressed +-- @element silo_cords +local silo_cords = +Gui.element(function(event_trigger,parent,silo_data) + local silo_name = silo_data.silo_name + local pos = silo_data.position + local name = config.progress.allow_zoom_to_map and event_trigger or nil + local tooltip = config.progress.allow_zoom_to_map and {'rocket-info.progress-label-tooltip'} or nil + + -- Add the x cord flow + local flow_x = parent.add{ + type ='flow', + name = 'label-x-'..silo_name, + caption = silo_name + } + flow_x.style.padding = {0,2,0,1} + + -- Add the x cord label + flow_x.add{ + type = 'label', + name = name, + caption = {'rocket-info.progress-x-pos',pos.x}, + tooltip = tooltip + } + + -- Add the y cord flow + local flow_y = parent.add{ + type ='flow', + name = 'label-y-'..silo_name, + caption = silo_name + } + flow_y.style.padding = {0,2,0,1} + + -- Add the y cord label + flow_y.add{ + type = 'label', + name = name, + caption = {'rocket-info.progress-y-pos',pos.y}, + tooltip = tooltip + } + end) -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.width = 16 - style.height = 16 -end) -:on_click(function(player,element) - local rocket_silo_name = element.parent.name:sub(8) +:on_click(function(player,element,_) + local rocket_silo_name = element.parent.caption local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) - if rocket_silo.auto_launch then - element.sprite = 'utility/play' - element.tooltip = {'rocket-info.toggle-rocket-tooltip'} - rocket_silo.auto_launch = false - else - element.sprite = 'utility/stop' - element.tooltip = {'rocket-info.toggle-rocket-tooltip-disabled'} - rocket_silo.auto_launch = true - end + player.zoom_to_world(rocket_silo.position,2) end) ---- Used to toggle the visibility of the different sections +--- Base element for each rocket in the progress list +-- @element rocket_entry +local rocket_entry = +Gui.element(function(_,parent,silo_data) + local silo_name = silo_data.silo_name + local player = Gui.get_player_from_element(parent) + + -- Add the toggle auto launch if the player is allowed it + if check_player_permissions(player,'toggle_active') then + local flow = parent.add{ type = 'flow', name = 'toggle-'..silo_name} + local button = toggle_launch(flow) + button.tooltip = silo_data.toggle_tooltip + button.sprite = silo_data.toggle_sprite + end + + -- Add the remote launch if the player is allowed it + if check_player_permissions(player,'remote_launch') then + local flow = parent.add{ type = 'flow', name = 'launch-'..silo_name} + local button = launch_rocket(flow) + button.enabled = silo_data.allow_launch + end + + -- Draw the silo cords element + silo_cords(parent,silo_data) + + -- Add a progress label + local alignment = Gui.alignment(parent,nil,nil,silo_name) + local element = + alignment.add{ + type = 'label', + name = 'label', + caption = silo_data.progress_caption, + tooltip = silo_data.progress_tooltip + } + + -- Return the progress label + return element +end) + +local function get_progress_data(force_name) + local force_silos = Rockets.get_silos(force_name) + local progress_data = {} + + for _, silo_data in pairs(force_silos) do + local rocket_silo = silo_data.entity + if not rocket_silo or not rocket_silo.valid then + -- Remove from list if not valid + force_silos[silo_data.name] = nil + table.insert(progress_data,{ + silo_name = silo_data.name, + remove = true + }) + else + -- Get the progress caption and tooltip + local progress_color = Colors.white + local progress_caption = {'rocket-info.progress-caption',rocket_silo.rocket_parts} + local progress_tooltip = {'rocket-info.progress-tooltip',silo_data.launched or 0} + local status = rocket_silo.status == defines.entity_status.waiting_to_launch_rocket + if status and silo_data.awaiting_reset then + progress_caption = {'rocket-info.progress-launched'} + progress_color = Colors.green + elseif status then + progress_caption = {'rocket-info.progress-caption',100} + progress_color = Colors.cyan + else + silo_data.awaiting_reset = false + end + + -- Get the toggle button data + local toggle_tooltip = {'rocket-info.toggle-rocket-tooltip-disabled'} + local toggle_sprite = 'utility/play' + if rocket_silo.auto_launch then + toggle_tooltip = {'rocket-info.toggle-rocket-tooltip'} + toggle_sprite = 'utility/stop' + end + + -- Insert the gui data + table.insert(progress_data,{ + silo_name = silo_data.name, + position = rocket_silo.position, + allow_launch = not silo_data.awaiting_reset and status or false, + progress_color = progress_color, + progress_caption = progress_caption, + progress_tooltip = progress_tooltip, + toggle_tooltip = toggle_tooltip, + toggle_sprite = toggle_sprite + }) + end + end + + return progress_data +end + +--- Update the build progress section +local function update_build_progress(parent,progress_data) + local show_message = true + for _, silo_data in ipairs(progress_data) do + parent.no_silos.visible = false + local silo_name = silo_data.silo_name + local progress_label = parent[silo_name] + if silo_data.remove then + -- Remove the rocket from the list + Gui.destroy_if_valid(parent['toggle-'..silo_name]) + Gui.destroy_if_valid(parent['launch-'..silo_name]) + Gui.destroy_if_valid(parent['label-x-'..silo_name]) + Gui.destroy_if_valid(parent['label-y-'..silo_name]) + Gui.destroy_if_valid(parent[silo_name]) + + elseif not progress_label then + -- Add the rocket to the list + show_message = false + rocket_entry(parent,silo_data) + + else + show_message = false + -- Update the existing labels + progress_label = progress_label.label + progress_label.caption = silo_data.progress_caption + progress_label.tooltip = silo_data.progress_tooltip + progress_label.style.font_color = silo_data.progress_color + + -- Update the toggle button + local toggle_button = parent['toggle-'..silo_name] + if toggle_button then + toggle_button = toggle_button[toggle_launch.name] + toggle_button.tooltip = silo_data.toggle_tooltip + toggle_button.sprite = silo_data.toggle_sprite + end + + -- Update the launch button + local launch_button = parent['launch-'..silo_name] + if launch_button then + launch_button = launch_button[launch_rocket.name] + launch_button.enabled = silo_data.allow_launch + end + end + end + if show_message then parent.no_silos.visible = true end +end + +-- Button to toggle a section dropdown -- @element toggle_section local toggle_section = -Gui.new_button() -:set_sprites('utility/expand_dark','utility/expand') -:set_tooltip{'rocket-info.toggle-section-tooltip'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.height = 20 - style.width = 20 -end) -:on_click(function(player,element) - local flow_name = element.parent.caption - local flow = element.parent.parent.parent[flow_name] - if Gui.toggle_visible(flow) then +Gui.element{ + type = 'sprite-button', + sprite = 'utility/expand_dark', + hovered_sprite = 'utility/expand', + tooltip = {'rocket-info.toggle-section-tooltip'} +} +:style{ + padding = -2, + height = 20, + width = 20 +} +:on_click(function(player,element,_) + local header_flow = element.parent + local flow_name = header_flow.caption + local flow = header_flow.parent.parent[flow_name] + if Gui.toggle_visible_state(flow) then element.sprite = 'utility/collapse_dark' element.hovered_sprite = 'utility/collapse' element.tooltip = {'rocket-info.toggle-section-collapse-tooltip'} - else + else element.sprite = 'utility/expand_dark' element.hovered_sprite = 'utility/expand' element.tooltip = {'rocket-info.toggle-section-tooltip'} - end + end end) ---- Used to create the three different sections -local function create_section(container,section_name,table_size) - -- Header for the section - local header_area = Gui.create_header( - container, - {'rocket-info.section-caption-'..section_name}, +-- Draw a section header and main scroll +-- @element rocket_list_container +local section = +Gui.element(function(_,parent,section_name,table_size) + -- Draw the header for the section + local header = Gui.header( + parent, + {'rocket-info.section-caption-'..section_name}, {'rocket-info.section-tooltip-'..section_name}, - true, - section_name..'-header' - ) + true, + section_name..'-header' + ) - -- Right aligned button to toggle the section - header_area.caption = section_name - toggle_section(header_area) + -- Right aligned button to toggle the section + header.caption = section_name + toggle_section(header) -- Table used to store the data - local flow_table = Gui.create_scroll_table(container,table_size,215,section_name) - flow_table.parent.visible = false + local scroll_table = Gui.scroll_table(parent,215,table_size,section_name) + scroll_table.parent.visible = false -end + -- Return the flow table + return scroll_table +end) ---[[ Creates the main structure for the gui - element - > container - - >> stats-header - >>> stats - >>>> toggle_section.name - >> stats - >>> table - - >> milestones-header - >>> milestones - >>>> toggle_section.name - >> milestones - >>> table - - >> progress-header - >>> progress - >>>> toggle_section.name - >> progress - >>> table -]] -local function generate_container(player,element) - Gui.set_padding(element,1,2,2,2) - element.style.minimal_width = 200 - - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' +--- Main gui container for the left flow +-- @element rocket_list_container +local rocket_list_container = +Gui.element(function(event_trigger,parent) + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' } - Gui.set_padding(container) - if config.stats.show_stats then - create_section(container,'stats',2) - end + -- Set the frame style + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 - if config.milestones.show_milestones then - create_section(container,'milestones',2) - end + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } - if config.progress.show_progress then - local col_count = 3 - if player_allowed(player,'remote_launch') then col_count = col_count+1 end - if player_allowed(player,'toggle_active') then col_count = col_count+1 end - create_section(container,'progress',col_count) - --- label used when no active silos - container.progress.add{ - type='label', - name='no_silos', - caption={'rocket-info.progress-no-silos'} + -- Set the container style + local style = container.style + style.vertically_stretchable = false + style.padding = 0 + + + local player = Gui.get_player_from_element(parent) + local force_name = player.force.name + -- Draw stats section + if config.stats.show_stats then + update_data_labels(section(container,'stats',2),get_stats_data(force_name)) + end + + -- Draw milestones section + if config.milestones.show_milestones then + update_data_labels(section(container,'milestones',2),get_milestone_data(force_name)) + end + + -- Draw build progress list + if config.progress.show_progress then + local col_count = 3 + if check_player_permissions(player,'remote_launch') then col_count = col_count+1 end + if check_player_permissions(player,'toggle_active') then col_count = col_count+1 end + local progress = section(container,'progress',col_count) + -- Label used when there are no active silos + progress.add{ + type = 'label', + name = 'no_silos', + caption = {'rocket-info.progress-no-silos'} } - end + update_build_progress(progress,get_progress_data(force_name)) + end -end - ---[[ Creates a text label followed by a data label, or updates them if already present - element - > "data_name_extra"-label - > "data_name_extra" - >> label -]] -local function create_label_value_pair(element,data_name,value,tooltip,extra) - local data_name_extra = extra and data_name..extra or data_name - if element[data_name_extra] then - element[data_name_extra].label.caption = value - element[data_name_extra].label.tooltip = tooltip - else - --- Label used with the data - element.add{ - type='label', - name=data_name_extra..'-label', - caption={'rocket-info.data-caption-'..data_name,extra}, - tooltip={'rocket-info.data-tooltip-'..data_name,extra} - } - --- Right aligned label to store the data - local right_flow = Gui.create_alignment(element,data_name_extra) - right_flow.add{ - type='label', - name='label', - caption=value, - tooltip=tooltip - } - end -end - ---- Creates a text and data label using times as the data -local function create_label_value_pair_time(element,data_name,raw_value,no_hours,extra) - local value = no_hours and format_time(raw_value,{minutes=true,seconds=true}) or format_time(raw_value) - local tooltip = format_time(raw_value,{hours=not no_hours,minutes=true,seconds=true,long=true}) - create_label_value_pair(element,data_name,value,tooltip,extra) -end - ---- Adds the different data values to the stats section -local function generate_stats(player,frame) - if not config.stats.show_stats then return end - local element = frame.container.stats.table - local force_name = player.force.name - local force_rockets = Rockets.get_rocket_count(force_name) - local stats = Rockets.get_stats(force_name) - - if config.stats.show_first_rocket then - create_label_value_pair_time(element,'first-launch',stats.first_launch or 0) - end - - if config.stats.show_last_rocket then - create_label_value_pair_time(element,'last-launch',stats.last_launch or 0) - end - - if config.stats.show_fastest_rocket then - create_label_value_pair_time(element,'fastest-launch',stats.fastest_launch or 0,true) - end - - if config.stats.show_total_rockets then - local total_rockets = Rockets.get_game_rocket_count() - total_rockets = total_rockets == 0 and 1 or total_rockets - local percentage = math.round(force_rockets/total_rockets,3)*100 - create_label_value_pair(element,'total-rockets',force_rockets,{'rocket-info.value-tooltip-total-rockets',percentage}) - end - - if config.stats.show_game_avg then - local avg = force_rockets > 0 and math.floor(game.tick/force_rockets) or 0 - create_label_value_pair_time(element,'avg-launch',avg,true) - end - - for _,avg_over in pairs(config.stats.rolling_avg) do - local avg = Rockets.get_rolling_average(force_name,avg_over) - create_label_value_pair_time(element,'avg-launch-n',avg,true,avg_over) - end - -end - ---- Creates the list of milestones -local function generate_milestones(player,frame) - if not config.milestones.show_milestones then return end - local element = frame.container.milestones.table - local force_name = player.force.name - local force_rockets = Rockets.get_rocket_count(force_name) - - for _,milestone in ipairs(config.milestones) do - if milestone <= force_rockets then - local time = Rockets.get_rocket_time(force_name,milestone) - create_label_value_pair_time(element,'milestone-n',time,false,milestone) - else - create_label_value_pair_time(element,'milestone-n',0,false,milestone) - break - end - end -end - ---- Creats the different buttons used with the rocket silos -local function generate_progress_buttons(player,element,silo_data) - local silo_name = silo_data.name - local rocket_silo = silo_data.entity - local status = rocket_silo.status == defines.entity_status.waiting_to_launch_rocket - local active = rocket_silo.auto_launch - - if player_allowed(player,'toggle_active') then - local button_element = element['toggle-'..silo_name] - - if button_element then - button_element = button_element[toggle_rocket.name] - else - button_element = toggle_rocket(element,silo_name) - end - - if active then - button_element.tooltip = {'rocket-info.toggle-rocket-tooltip'} - button_element.sprite = 'utility/stop' - else - button_element.tooltip = {'rocket-info.toggle-rocket-tooltip-disabled'} - button_element.sprite = 'utility/play' - end - end - - if player_allowed(player,'remote_launch') then - local button_element = element['launch-'..silo_name] - - if button_element then - button_element = button_element[launch_rocket.name] - else - button_element = launch_rocket(element,silo_name) - end - - if silo_data.awaiting_reset then - button_element.enabled = false - else - button_element.enabled = status - end - end - -end - ---[[ Creates build progress section - element - > toggle-"silo_name" (generate_progress_buttons) - > launch-"silo_name" (generate_progress_buttons) - > label-x-"silo_name" - >> "silo_name" - > label-y-"silo_name" - >> "silo_name" - > "silo_name" - >> label -]] -local function generate_progress(player,frame) - if not config.progress.show_progress then return end - local element = frame.container.progress.table - local force = player.force - local force_name = force.name - local force_silos = Rockets.get_silos(force_name) - - if not force_silos or table.size(force_silos) == 0 then - element.parent.no_silos.visible = true - - else - element.parent.no_silos.visible = false - - for _,silo_data in pairs(force_silos) do - local silo_name = silo_data.name - if not silo_data.entity or not silo_data.entity.valid then - force_silos[silo_name] = nil - Gui.destroy_if_valid(element['toggle-'..silo_name]) - Gui.destroy_if_valid(element['launch-'..silo_name]) - Gui.destroy_if_valid(element['label-x-'..silo_name]) - Gui.destroy_if_valid(element['label-y-'..silo_name]) - Gui.destroy_if_valid(element[silo_name]) - - elseif not element[silo_name] then - local entity = silo_data.entity - local progress = entity.rocket_parts - local pos = { - x=entity.position.x, - y=entity.position.y - } - - generate_progress_buttons(player,element,silo_data) - - --- Creates two flows and two labels for the X and Y position - local name = config.progress.allow_zoom_to_map and zoom_to_map_name or nil - local tooltip = config.progress.allow_zoom_to_map and {'rocket-info.progress-label-tooltip'} or nil - local flow_x = element.add{ - type='flow', - name='label-x-'..silo_name, - caption=silo_name - } - Gui.set_padding(flow_x,0,0,1,2) - flow_x.add{ - type='label', - name=name, - caption={'rocket-info.progress-x-pos',pos.x}, - tooltip=tooltip - } - - local flow_y = element.add{ - type='flow', - name='label-y-'..silo_name, - caption=silo_name - } - Gui.set_padding(flow_y,0,0,1,2) - flow_y.add{ - type='label', - name=name, - caption={'rocket-info.progress-y-pos',pos.y}, - tooltip=tooltip - } - - --- Creates the progress value which is right aligned - local right_flow = Gui.create_alignment(element,silo_name) - right_flow.add{ - type='label', - name='label', - caption={'rocket-info.progress-caption',progress}, - tooltip={'rocket-info.progress-tooltip',silo_data.launched or 0} - } - - else - local entity = silo_data.entity - local progress = entity.rocket_parts - local status = entity.status == 21 - - local label = element[silo_name].label - label.caption = {'rocket-info.progress-caption',progress} - label.tooltip = {'rocket-info.progress-tooltip',silo_data.launched or 0} - - if status and silo_data.awaiting_reset then - label.caption = {'rocket-info.progress-launched'} - label.style.font_color = Colors.green - elseif status then - label.caption = {'rocket-info.progress-caption',100} - label.style.font_color = Colors.cyan - else - silo_data.awaiting_reset = false - label.style.font_color = Colors.white - end - - generate_progress_buttons(player,element,silo_data) - - end - end - - end -end - ---- Registers the rocket info --- @element rocket_info -local rocket_info = -Gui.new_left_frame('gui/rocket-info') -:set_sprites('entity/rocket-silo') -:set_post_authenticator(function(player,define_name) - return player.force.rockets_launched > 0 and Gui.classes.toolbar.allowed(player,define_name) + -- Return the exteral container + return frame end) -:set_open_by_default(function(player,define_name) - return player.force.rockets_launched > 0 -end) -:set_direction('vertical') -:on_creation(function(player,element) - generate_container(player,element) - generate_stats(player,element) - generate_milestones(player,element) - generate_progress(player,element) -end) -:on_update(function(player,element) - generate_stats(player,element) - generate_milestones(player,element) - generate_progress(player,element) +:add_to_left_flow(function(player) + return player.force.rockets_launched > 0 and Roles.player_allowed(player,'gui/rocket-info') end) ---- Event used to update the stats and the hui when a rocket is launched +--- Button on the top flow used to toggle the container +-- @element rocket_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'entity/rocket-silo', + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/rocket-info') +end) +:on_click(function(player,_,_) + Gui.toggle_left_element(player, rocket_list_container) +end) + +--- Update the gui for all players on a force +local function update_rocket_gui_all(force_name) + local stats = get_stats_data(force_name) + local milestones = get_milestone_data(force_name) + local progress = get_progress_data(force_name) + for _,player in pairs(game.forces[force_name].players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[rocket_list_container.name] + local container = frame.container + update_data_labels(container.stats.table,stats) + update_data_labels(container.milestones.table,milestones) + update_build_progress(container.progress.table,progress) + end +end + +--- Event used to update the stats when a rocket is launched Event.add(defines.events.on_rocket_launched,function(event) local force = event.rocket_silo.force - local rockets_launched = force.rockets_launched - local first_rocket = rockets_launched == 1 + update_rocket_gui_all(force.name) + if force.rockets_launched == 1 then + for _,player in pairs(force.players) do + Gui.update_top_flow(player) + end + end +end) - --- Updates all the guis (and toolbar since the button may now be visible) - for _,player in pairs(force.players) do - rocket_info:update(player) - if first_rocket then - Gui.update_toolbar(player) - rocket_info:toggle(player) - end - end +--- Update only the progress gui for a force +local function update_rocket_gui_progress(force_name) + local progress = get_progress_data(force_name) + for _,player in pairs(game.forces[force_name].players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[rocket_list_container.name] + local container = frame.container + update_build_progress(container.progress.table,progress) + end +end + +Event.on_nth_tick(150,function() + for _,force in pairs(game.forces) do + if #Rockets.get_silos(force.name) > 0 then + update_rocket_gui_progress(force.name) + end + end end) --- Adds a silo to the list when it is built local function on_built(event) local entity = event.created_entity if entity.valid and entity.name == 'rocket-silo' then - local force = entity.force - - for _,player in pairs(force.players) do - local frame = rocket_info:get_frame(player) - generate_progress(player,frame) - end + update_rocket_gui_progress(entity.force.name) end end Event.add(defines.events.on_built_entity,on_built) Event.add(defines.events.on_robot_built_entity,on_built) ---- Optimised update for only the build progress -Event.on_nth_tick(150,function() - for _,force in pairs(game.forces) do - local silos = Rockets.get_silos(force.name) - if #silos > 0 then - for _,player in pairs(force.connected_players) do - local frame = rocket_info:get_frame(player) - generate_progress(player,frame) - end - end - end -end) +--- Redraw the progress section on role change +local function role_update_event(event) + local player = game.players[event.player_index] + local left_flow = Gui.get_left_flow(player) + local container = left_flow[rocket_list_container.name].container + local progress = container.progress + if config.progress.show_progress then + progress.destroy() + local col_count = 3 + if check_player_permissions(player,'remote_launch') then col_count = col_count+1 end + if check_player_permissions(player,'toggle_active') then col_count = col_count+1 end + progress = section(container,'progress',col_count) + -- Label used when there are no active silos + progress.add{ + type = 'label', + name = 'no_silos', + caption = {'rocket-info.progress-no-silos'} + } + update_build_progress(progress,get_progress_data(player.force.name)) + end +end ---- Makes sure the right buttons are present when role changes -Event.add(Roles.events.on_role_assigned,rocket_info 'redraw') -Event.add(Roles.events.on_role_unassigned,rocket_info 'redraw') +Event.add(Roles.events.on_role_assigned,role_update_event) +Event.add(Roles.events.on_role_unassigned,role_update_event) -return rocket_info \ No newline at end of file +return rocket_list_container \ No newline at end of file From 80b9672a5703634298e3a9319afebf84cdd4b1f8 Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Tue, 28 Jan 2020 17:26:01 +0100 Subject: [PATCH 09/81] ratio added ratio added --- .vs/VSWorkspaceState.json | 10 +++++ .vs/slnx.sqlite | Bin 0 -> 131072 bytes .vs/vs/v16/.suo | Bin 0 -> 29184 bytes config/_file_loader.lua | 1 + config/roles.lua | 2 + locale/en/commands.cfg | 9 ++++ modules/commands/ratio.lua | 85 +++++++++++++++++++++++++++++++++++++ 7 files changed, 107 insertions(+) create mode 100644 .vs/VSWorkspaceState.json create mode 100644 .vs/slnx.sqlite create mode 100644 .vs/vs/v16/.suo create mode 100644 modules/commands/ratio.lua diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 00000000..e9c346db --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,10 @@ +{ + "ExpandedNodes": [ + "", + "\\.github", + "\\.github\\ISSUE_TEMPLATE", + "\\utils" + ], + "SelectedNode": "\\utils\\math.lua", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..178ee98162dc3c46dbc742eb33b7ae791811a739 GIT binary patch literal 131072 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 SZS5JCL&ABE^E|zkm1^Hq6NJqG literal 0 HcmV?d00001 diff --git a/.vs/vs/v16/.suo b/.vs/vs/v16/.suo new file mode 100644 index 0000000000000000000000000000000000000000..c5280cd230ef6c1567149876e6d5aeccf8891d61 GIT binary patch literal 29184 zcmeHQ4UiPab)H31EdGCuY=O{$FgnofYWMbj5h5J7cYp*EaCaP_L&tKv91DB9$Nn53 zK(Zy-SVmGLW7#nxPPyX9KdMyhSaK9Au5uJBP9>F~BskcW#FFJ$3bJEclwt`JAm2AL zeLFL^Gt;xX2RNpWH{H|I-LL!g>({T}b~mpapZeP8zjpnP6pLG`T&0}9Fjn~;L%a{+ zG2(rSqFjwI)mt5ao z@v*(p6W{ZVN4gK+s3l$tjA>=3vI^L@Bh;qsbt%RCc_uj0NN)4j;%^5L4fa)?z)!q` zN)k25C~-gsXb}a(^>lXLd}WN!EB?tSY(OvYZY2*aNhN{y6Z#F9BZ$e^A=cx8Umb@5 zyt5uI$<@z6JU8f_^*)5p85@8w$1~ln__heZvYBTBU?PBB$2O3LQvuTe(*ZL8?+45T zTnG37;Ddnc0kZ(J0XG2V0EnXs{#?L3z)gU00OIAh8a+G~el;KjSO};Gd*1(3S7+bzwE<@hQ~hyj_SntyO`tu0bu@rH2!^@hf5v*f-^YJ zQx1r6!?DkA9RGEIi#7gl*70)uvo6KPKkG$j9siBUL%A?tFGI9NOMT^8i~`i(sMAq* zBfYFZ`dj0~JI9a+3;EA?8TrpSqzYh^|Liv*+sOx%`;__QLH4!a34xP7=LInbkWV>3 za2_BpGy$3civhO*mH=)CECu{7U>TqVupH0|hydCE#`0I;{SLsLfYpFCfV%*91J(l8 z0oDUL0G$Alw_6Wy(*1jMe~a$->V8!B`*c69`~A9~(EVMyPrZRS(z?G}_p`d6hd-o; zsYx;IeY$@@_wUzze)A!GrT>4s`k(zS+;V8VX=NAm(I|AyT?XwFj3MD>L;ocYasFVL z5?K_^Egai)oxqy~-qp}`v(SV)lpU%Lo>Tf%&6s@csP1P*doIENZj^{WO3+>74iPJGvLHp6^@njZ+&RJo4)j z>eLM)6Gd9t1KlQya1>onc@%(bq@Pn|^tNFM%^Wer?m$(jLyhrqZSSS~Df?(EpmW0C z4IGqrcf&G6KMuTBR}1+oaMQPbw|(cN1=j(B_vx~hGC!uaIe_@I%Jdu%BzyqvPlGlw zRTAeBlT-6A1%BF4XzP&0-;T6m{_%pJGi46iYDVp+K2S%czvuR^Kt9gbbZlEM=*zjL zA5YFaWHD{PYxbT+(2R=<32F`GghG1u>wHssva)7bBt;7;Ib$z1rS!`FS}TI4GK?b3 zJctUICjs*YQ?3Boo={tohsf)JHL?SLU6`GF!ToI*8Eeu1Eo!(2J&;HGUX@ydXdTB$ z00WZTDdu$qJ-J{0??c^x(z)e%PnnQ-Aezm^Gn1B zI2!xAF|(E_TNWbx^>??Pd;Qe!A7=Q%q<6a3JhSM9xdAw9?fbl=L zuV(X2v*yoWn6zfQ*?wIdAT+oP4{1leuaH+dTg4Jq0yo!xR##4(wXD&6_mxTgQpc-k z6X{QRVw8~Ln~Yy>|B?SD>xhiJ*o8Qjy)p>Xo$=2<{N@}o=3#i0+*Fji2J$os8Jd91 z<*zQ3r+LgtVg*F2%~h&}>NeFDxgV0a7AvJTSb6I33@LudWQM~Ch42?ah5bmyZ!HM1 z0WE-5*n@(|$-h>lJ_xxTgXUw#OMQd0JF(Kyc4X&_{q8h>wE)imT9`s@S}|jC-Yh6` zOE8OQI?hu3!ZOapP3BVhD_H`w4^?!QIi%|X)Q$XxcF2{TR}Rk=zun{`i-Y*v-%{J& z)>zjT@-J_!3;RQ%NYLNX7HaVagDt_<=3sk!du#aMfhB7a*}nEfGM-&}AhNh;DBF|I zC6d{mfoN_=AeoOIIIuswyg67Kstx21-Z7reR3;LRtzAgv6E`_dUtBz~aGrpD5J*`B`iz(6z=%l0f! zr}Ejrj@&>}ma+DhiC<%9y#ijyU2elQ#DmG`zIdiL6WA#{s-vT;t+%sn&Dzy1oozks z@n|lei9;&w&d0O4z(7oPlsrC4HHyTu`%-uC}Sk z-`o(}?yrwWw}+eS;_+}pb08QD;U9m3HMtKczG6#lq^S@AysF06iVUWLTS%t(qp~T}vNV$THK&1+LK*AcU0&e2-j`WyAaWwPnV16AA3&Myv6cTA!XaQWc+L zB#GzG6(AIMpa{1I0a{TiBrm+K^R5*cO!C4pvH}EHDO#`izr7XVdJ^E0E&0Y9mWkIH zc|#(;0>lvZKhk6)045zJav3cHXFIJWtBv%kNWuzG^wT7z?znrIJ1okcj!IqWO|fRw zCnd>fX>v5w)p}7+F8WG)?C{!rvc@yE@1xb^OJL7{Xc@MFOx2q07$e1^zmr6!dnWH=OT_M$>vesf^rJ=G%gm}e*RcQ|J}x4|2pcC>;!yYj#k*KzH}8+%La5q4^oksta| z(g1RbearIsMjqUd&uct%;gpLz*?3<=0CzXI^PI6=);;4+Sd962J3|z=Q;<)zz1Ms2 zPW~zES9dDQ%#CJQ)QM8bfrZ`N;)sQ{#7fKNjmNnUzH~PqJ0Hy___9hBcDHlKV+g&& zr<3CkZz~=48=C3lyo*u6T_6gu8}~$xJ@;vW6fb99F4ASyEJDnT;u$IjB$@_1pK-U0d@pEtYLwbpB_?@LE&pK)M z|8Rr6EPnoCOA{2G8~!>ine9{HCvH01goY3M5GK&M;jh(_**-~s4YT&NO=$SAAK`_ju5`;pbfYa8LuHnTkC50L^0YBGJ+$AE5pZBkb z5{#6!p1)rUtSS8QY*#z#sM!MwcYm-9w11fPviP}5qv4UxN`G-53GW0TUcQqS1uN4C z{66;OOn@wY{upl8|GfW%xOx7bRus28SSbIv|LH>>@N>n@bH8-f_80K)gY|_s!X&kX zHqTPzud)BF_}75e11gvAGmSbk)eDuW(fOaWrz?E150Unr`saXgv2I)(6+b+G-;bZm zt$OS$@0~sQ^QR|%<*VxKs39&q?GYFGV!Hprh+oFsGkN;?<3IiG(YJ0rH?I4gGYg+% z`GtCDp&~eqQETnmZ@*-6zB1wHhF`S2wQ}W(FV9{4#QQ(G=@yqd%`@UJZa}VI_~H!@ zJ~(N`%2)5d{_59HyOn5coqM=dwW{&XhYhNX+oRrZLCI&mX{dNvrRYCS{ND{J$Ge|+ z^M@VJ8*5Tkg8ZYdXgB_g&woaY=5RH}-;Icx4j{vszZQR+h-l6ibk_0jCU3P|g=Z=9 zhq7PDUpM_Lq~4}iz-JAWqJM2eA@cff*oxBh&i2nn%uN7U`p1wqub1N9{>tm0+ku;R zu+X{VceX&V{R>b|H9)rgJCL>&K<9?vdG)2*Kh*o&E}{L$cg6n0p4Xh#tIkiO{bvod z-7eVdt@j;OLE{uR(K(gI@jnd-ZU(RhPHDxrl?dFxPJ_D#8fFZbG|hesYO)%#fm%3k zB-g$$ju&HbX3&1=)bjEP{aeMWH(v^W7xK;3i*V!rka~ltp16p|@h5Q0wtoZ45$jKP z{7pr$7NSW1D!k4C$l~W2fpq}7h)UVK`b#5cedBs$Exu*dzR{>&Y(5U6{j_d#K9$AK z`Iq-j&^h7n0(P!RBWlk_wG5VLpal9G^$#oGx1!DBmj;Zlqmq&_H(>E zqZe{F))+g%4ZM3x!(Gt4HmEn)>IrQ;+&}4~K0(}cHpxuUw3mrPha87oKaEvy9YKGn zcX=4Lm><|5)E#aB2?i|>@$KM&`sSMY<^%1~WHx>e%G1ixPT)D6>X0qIwxOn0FMhqH z_>l*&WD5<2nrlLhTBYx>lxjG-BU@ZkQ%yLml~$;u-Hun;LPNEUHO+b*sWcb~D^6L- zmet%)Q?FMrq8ByCxc(UVW9|QZtNX7X`sP#b-uHtk|1m~+?IXxF%xW6L$*~;s6?LZj zCuwqU+SW4Vi$jNh_(#(>ADdBg^~1h~tt?U0Lik0o*hj85w%`5-N4X#Rp4oNw%(`z&I)J^!1xe%No3dHTrF^9w$8R#|Xp;*-z) z@vJSLYSu1`-+AlFS6}UY%6HAqH@3fV`-xA78=sc0!@WlQ-ZomuY-@Py=r7kjd2m`| z=w$C-ok&0OCFy!Gp^V#Hdi`m7$X?O^X>=_9|L@QiBdh;&mCh+hrq3=X{oj54QR~s+2OZW5l@{yPsiSzEI<9FUhc&>iJ>F>WcyZZcpjh!;@-aGB;@R?&T zePdd{+x@$h?thw6uJk`H#Pl|QSET=K^*8G_XaA4Sb$#*0u`8Cna`nGPe)T!(j3aqE Zg>l(|`G{7Bxcb|x+xRbq|BU1R{{W4&Uta(K literal 0 HcmV?d00001 diff --git a/config/_file_loader.lua b/config/_file_loader.lua index c4a5bba6..7521e087 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -13,6 +13,7 @@ return { 'modules.commands.tag', 'modules.commands.teleport', 'modules.commands.cheat-mode', + 'modules.commands.ratio', 'modules.commands.interface', 'modules.commands.help', 'modules.commands.roles', diff --git a/config/roles.lua b/config/roles.lua index d46d08fe..36aced14 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -210,6 +210,7 @@ local default = Roles.new_role('Guest','') 'command/list-roles', 'command/find-on-map', 'command/report', + 'command/ratio', 'gui/player-list', 'gui/rocket-info', 'gui/science-info', @@ -285,4 +286,5 @@ Roles.override_player_roles{ Tcheko={'Moderator','Member'}, WhomstThouAmMe={'Moderator','Member'}, Windbomb={'Moderator','Member'}, + tovernaar123={'Administrator','Moderator','Member'}, } diff --git a/locale/en/commands.cfg b/locale/en/commands.cfg index 2fdbea0b..ab475d4b 100644 --- a/locale/en/commands.cfg +++ b/locale/en/commands.cfg @@ -59,9 +59,18 @@ result=__1__ entites were revived and __2__ were healed to max health. set=Your bonus has been set to __1__. wip=This command is temporary and will be replaced at some point in the future. +[expcom-ratio] +notSelecting=Please select an entetiy with a recpie. +item-in=You need __1__ per seconds of [item=__2__]. +fluid-in=You need __1__ per seconds of [fluid=__2__]. +item-out=This will result in: __1__ [item=__2__] per second. +fluid-out=This will result in: __1__ [fluid=__2__] per second. +machines=And you will need __1__ machines (with the same speed as this one) for this. + [expcom-home] no-home=You have no home set. no-return=You can't return when home has not yet been used. home-set=Your home point has been set to x: __1__ y: __2__ return-set=Your return point has been set to x: __1__ y: __2__ home-get=Your home point is at x: __1__ y: __2__ + diff --git a/modules/commands/ratio.lua b/modules/commands/ratio.lua new file mode 100644 index 00000000..e96fd2e3 --- /dev/null +++ b/modules/commands/ratio.lua @@ -0,0 +1,85 @@ + + +local Commands = require 'expcore.commands' + + +Commands.new_command('ratio','Will give the ratio on what you have selected') + :add_param('itemsPerSecond',true,'number') + :register(function(player,itemsPerSecond,raw) + + local machine = player.selected -- selected machine + if not machine then --nil check + return Commands.error{'expcom-ratio.notSelecting'} + end + + if machine.type ~= "assembling-machine" and machine.type ~= "furnace" then + return Commands.error{'expcom-ratio.notSelecting'} + end + local recpie = machine.get_recipe() -- recpie + + if not recpie then --nil check + return Commands.error{'expcom-ratio.notSelecting'} + end + + local items = recpie.ingredients -- items in that recpie + local product = recpie.products -- output items + local amountOfMachines + local moduleInvetory = machine.get_module_inventory()--the module Invetory of the machine + local mult = Modules(moduleInvetory) --function for the productivety moduals + + if itemsPerSecond then + amountOfMachines = math.ceil( AmountOfMachines(itemsPerSecond,1/recpie.energy*machine.crafting_speed*product[1].amount*mult)) -- amount of machines + end + if not amountOfMachines then + amountOfMachines = 1 --set to 1 to make it not nil + end + ----------------------------items---------------------------- + for i, item in ipairs(items) do + local sprite -- string to make the icon work either fluid ore item + + if item.type == "item" then + sprite = 'expcom-ratio.item-in' + else + sprite = 'expcom-ratio.fluid-in' + end + + + local ips = item.amount/recpie.energy*machine.crafting_speed*amountOfMachines --math on the items/fluids per second + Commands.print {sprite,math.round(ips,3),item.name}-- full string + end + ----------------------------products---------------------------- + + for i, product in ipairs(product) do + local sprite -- string to make the icon work either fluid ore item + + if product.type == "item" then + sprite = 'expcom-ratio.item-out' + else + sprite = 'expcom-ratio.fluid-out' + end + + local output = 1/recpie.energy*machine.crafting_speed*product.amount*mult --math on the outputs per second + Commands.print {sprite,math.round(output*amountOfMachines,3),product.name} -- full string + + end + + if amountOfMachines ~= 1 then + Commands.print{'expcom-ratio.machines',amountOfMachines} + end + + end) +function Modules(moduleInvetory) -- returns the multeplier of the modules + local effect1 = moduleInvetory.get_item_count("productivity-module") -- type 1 + local effect2 = moduleInvetory.get_item_count("productivity-module-2")-- type 2 + local effect3 = moduleInvetory.get_item_count("productivity-module-3") -- type 3 + + local mult = effect1*4+effect2*6+effect3*10 + return mult/100+1 +end + +function AmountOfMachines(itemsPerSecond,output) + if(itemsPerSecond) then + return itemsPerSecond/output + + end +end From c0b2a99cab8793ef0e7897d85bbd2513ed7a44d0 Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Tue, 28 Jan 2020 17:37:27 +0100 Subject: [PATCH 10/81] Revert "ratio added" This reverts commit 80b9672a5703634298e3a9319afebf84cdd4b1f8. --- .vs/VSWorkspaceState.json | 10 ----- .vs/slnx.sqlite | Bin 131072 -> 0 bytes .vs/vs/v16/.suo | Bin 29184 -> 0 bytes config/_file_loader.lua | 1 - config/roles.lua | 2 - locale/en/commands.cfg | 9 ---- modules/commands/ratio.lua | 85 ------------------------------------- 7 files changed, 107 deletions(-) delete mode 100644 .vs/VSWorkspaceState.json delete mode 100644 .vs/slnx.sqlite delete mode 100644 .vs/vs/v16/.suo delete mode 100644 modules/commands/ratio.lua diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json deleted file mode 100644 index e9c346db..00000000 --- a/.vs/VSWorkspaceState.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "ExpandedNodes": [ - "", - "\\.github", - "\\.github\\ISSUE_TEMPLATE", - "\\utils" - ], - "SelectedNode": "\\utils\\math.lua", - "PreviewInSolutionExplorer": false -} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100644 index 178ee98162dc3c46dbc742eb33b7ae791811a739..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131072 zcmeFa34B~t^*H|Cyf^R7d-Im0ZJK@UnzoZRNheDeN}8l?x~56GQ9?SInWRG}nJ_cy zf@PUulU+a-5kwH#WDymVMOg$?P*FrtTtHD#R1guAO@HU!`}Uc%{P6$t`_=#J=hJud z?m2fm_ug~Q_U`m=-55(pYeo{uu~53EnJS=YnmV?ohN37x{70$&Z#w+J>MxMemcOU^ z(@zE7Kgo-b)prrjH1%ES7OB9$LA*#f-}h6V;kGiDc;5E(dDc%=g`5AMK><$Xa7Qz< z6~1^!fX-}r*Tmw{p2$#7J|wlXue)QQyQXJz zSNG1E-5;oqL0PPUe_J-^;t$r$-)(Ppus%~H^TnOe&9(Wvxj8fz&EGlYD4jD)9;HhN zaj>Ry%f^jptedxVcJz1GpS4orivt1ryg)iM9FIDO?tGWE&J1*{-q@XI!gb02w+vy1H$k zuI`Q9CP?oLA>iii9ethaI{M}}1%vfQhaGg)i>#T9#}93t48>z3v1lY;1@`&S%WZ&F zV$w?=u@3DBhoh-fY&aH2Lo~?hM02dc96WQ#Rsy1p(tjwGj*b~5bY>w^)|jO~3@tY% z!XdOj`w|DH9)OP2nTSu0jpyRYVtr<@pD!MQeKmyl74B&`G(H|pc80=xqeHn}C%epv zDA{+J6Fg--mObYz18Xn0^}+fxwuyMhojr(moU@ek-EZGHyOx@SJXj?*SI zU!QYUj%~-`c8|Vb{|m$)n>K zg)GZUhiLrk(ZRBwM1>}${tw5&iK zV4b87u=2>tFgi?zW3t&LN9D45yT(vINMST(%Xq%HJD^XQb0H7)hLX|o^blg(PM9z6 z{5i3#HCU$7iG~D*e5dmwIL>evoCVNY&aCG6;(fsR4w;eA!XS#gRI+u^|^=GVO36t(LnY4vk&VG9B8^j5= zY!N5u!)+DPXLFT*07+!ZIWT!0=3_{nLjOL5Nbs+5_?{G^&0x*yo?J0-VCnT&LDIE%Dgu*sbMSmYkOJZ(C{GL-9$NN5|^i2HIMoD8rMJen_dm zQy)@qmd}v)z>E9OrGQHTmjW&YTne}pa4FzYz@>mo0ha>*DHO=~I4{+i83Z%biP3Pn zGci6A8=XvI`*uI*tg&$PBS<%{(-2lq#^MnhR;q4U&F(>LWUT8?hmz^Z2@MzN#8zl0 z(QxfZPf*W1u)^K zb4ycTX;W(?0G(YLXkFSg(iClK3bw$Y+Li>HTZ7PvNK50=z|zK%ARx6j2ZC)&n@6H8 z&CyU>Qy|>Z)Yj4(4hLFVLv4Yj?ctU{s6DbI&@>z!X>Mtcv<;861|scEjZNWTB+%X( z3;|LUkXnPyfu@mQTg&js@W_%@KpF|R2HP9k18tEI^l5l$I4~Sp8VoeH1S3tu;gOb+ zmc~GIq`fUV+`c3*JkmZ46ptVHNkAPw!kv7cIun!Q>Be~;mI^d?CZnNrG_obRZ6bpHSkee{9cY4n)HJp%YhJpnF*uWEsd>fy z;DH$nX;#_BhUSJK(*Hf`&nWc`c)0&u3b+(-Dd1ATrGQHTmjW&YTne}pa4FzYz@>mo zf&VxP6nU6{#~I&3NBlHXPHPq@PJ~f$>Rw8HUj3;0n0kx4SAFe2ZlG?5T?)7qa4FzY zz@>mo0ha6|d&$V;49P9m^_bKn^y_b6rdr$Bl>#bn_$-cne%U;MH z$1Y(d<|XES<{V}>)5sKfUiCcbxz&^PggnbUGwDCjPt#wZucS|=x6>_j`4JaK=|?!K zmKL~yP-#UuN|lSAVPLO(# zJu9#=5rS{f?e)}+lRkIFQb6@cpd%hlI>}Qr#!-u*GhGlbvlnU^9d*`H9Vg9nCdMXW z@lZOM7`Hbwe;-G!f+_%EEHoZTHB5w(spwELccK=Y$WfiSn4?kn7CIES*V-84sI6Aq z&}4e=P!d9X;KQk*NGyf!0%rUgO5kf(IXaV>{E#+u+ ze$+mEf)mKIP8%ckAq6^MNP#{wqyWrPo*{+pJ=Kcj8Pae*#E#q{RfWh#?c5tm2Vhgg z57~)WzK3k4)rs-RlyimG4H0^DMD~YZheiT8$j@Fu#R(iW4`yLUC^-&mpDfyDoljH@ z66ioQ9-T-e$;vmN#m940C6pZqkv(GoN_UgpkJ$@u&jcOkWDEwVe3!-;a8r(+lqd-qCu31kg?OlXIcZXuMyr>Y$^Ycod$p&y;` zXeb%z8Q%{d6(^EpX&Ak!+N3WXU>1Q*iHM_5r5j28cdui8M0;sqH%YtI2+pZEA^ z(w9wL4_SD5jt>K8&blM9UjwafEvYIGw>NRt5S%=m)4-|eo`Q247`0s-)d)oG3XQ>G z5x_?WS%d~kb!UF&Y9Lgt)@g3rt_HliL#qI7=X@>H9XsWgH7Y4u#ZjfSk4q;eV&Rm4 ziT=*>GpdduZKoz6WH=dZK8W1Zbtp|abfM;GXO3PHrDg$*3A zfXT6E1y?U3Yiei&B#WUqkt_g#(|cO7kkI5nC<#J|6;i%{FiwCF=5Ga-)RSUqEIwKx zmGeo5Qb>9ng8KwQwpwfFk&T4J7$iIn0h0pZ(ON^9lB}Xf)bQW1{Ng_B}LG$a#kw1au#-Rx;$PI-xxzUPQTT6OAfyBlkxR`^8jaHP| zHDnh}=u+d*s3tYqu&OmILnZ_?EE8I>s;kh<`MBu83AE?~`qDIJuC|i&2jnLt5)Ork zNNB60g3NvdNrW)_SR%9{RF#u;43!%Kp%q?PMkX^1ENKX+2NH%ATvkeGKCB5CR#0U^aFNWYE6Oa*XD8(8|7~h>WJef`-u46-)Nl@0n2qu#tiJ~vtLC7A9Ow(6zRS_9O zcQTnsqD~@F!~(CLL5R>5O&uB!=Rv5LPUM)?lcRZ{mD3Ojd|Xd||F-U-f$mMc=t3)x z-um=Hjw+^n94HC#6wdtHn=cd>z$%4ISW}>WKtQ_zfNR96DbQfLJGwS?LofAeiWFd3 zP(tIZI{pk9*bijK;r^m{RL?Dv5VF8+?CI>@+~2L&QS2v`$Hqqz4JW1&<2s;7B$aDR zNv~#_06Y~c2c}Irh;%<65DTh~L{s5pYy!=Tt*TNUW*p!e%SCggw=#nxeI?vg&n@(F z)O2X1VZYHvDNE{T7>%W^$6?*;^%Qx?7!YLdnl80_ipBXVOFB z{X#-Hti0pD&3}ckTZxG`i5E(z2*(JuzIS{-^F8Lf*>|2V%+>iieRDX$pYata+tkl{ z>ew6DEE{7tv5Q%i`4w{yb1Ji$sgV+%_dP%NJm$H>bD`%X&koPAQdrvIDNsL6za?$< zpXeXp-%*YgPgT!Xe&b)k|4OM>v?{mKmbr}U%rjr2L*x0L(&?}!uL-$~u#us9&K zsC&f@RT7)IPm6P;dZ|J^Ufn8|s@+n7bgOhZ{{{IS?^FKS{I%Y+U*NOyi~Nc5xA+b6 z=eP?*pV}(?onJ0rBfQL=tk!!^;1_UvW(Ff^sn;?-Bo1Fv~sK z+G~JQy&((|sivAzcU3YgZ9tt1Ad>`jX9?46KoJMj6jthvGN#oAz}hMO!Noqch}nIVVus30U3*ky(-J^kW1*Pi(8Mi& z(y|zACnknoZJArkafo4`uuPJE7Gl6vmL?qsA%++JXG4Uj9(b;` z1${Z%SsEDiDPRSD9M!D>^|k}#5XN<1HiKE{*@48qfMK_yE}hQQdyq}gl6MJOnf*i< z1AP(>7hL{hMG$~R>~xmgi&3uA97bJ)cHTfD5g!f_!xnX+!c=?uCnH*A7pP3FryulG zqK8uFqj%HpLY;?3+G{N16qw@-D;jmK%v5^T0%O7b`sg%fo~QfZM1T5_W>uojLG#mz z*$0ekI2qE^Vd`vzivTA3I19Cm$wI0-6QRJnX#k*5!$x~@G1E-vQLGOY zFmoW^w8b7ob(!=%fZ)~<>{pptbf0NwovdOyp!-wVR@126-duZXs*Gue{CqalBr@SU z7s^Q(-%sxG za=8=dGFwgflw2)V!K`$m8C+~{F3{v!qiBSB2P`(r5o@<|?37V!x2CpDMyxG6?UCVJ zAU65nr8|rkAF};e?2aL{h^)58J*e+_?2AJ=OZxUbx%7 zc#p%2*Rt7mITr6uj9{_5j?RotO!LZ@=;WyoG zw-vn^wz^)_OVd8LrGyF6`D}8V2`O!MxJ{_6X?xp|3i)T@IVp zF{Mnao@cjXtwhtVX&fui`qJ%H%Z(SXQ7uEXH|`Xy4{hFv2k1R!XhP9)m8FiVQ#Z9QoRyG4FR3jp4j;&}3+JJdk3KUt4mZse%)L>*0 z_5oM{L|2<&3z>^hKM&~ko`q<0z?)&?S%AQ4-L6xQDz(V6P<}p|>|FcJJhba9Hk-Mq z9>Y#E2SIfK7Al#Is0`9Ma^%75EX2;Hw87M&79Bz^6skoto!8b%7AKF zQOq=YCXz9@9W}8(noPnS-3XuF1+elXXo3*`Pe-`(DD^${Z|YyvKfyhKFR8y!f1*CC zKCM0p_JD`g2h@AjyVcv(o8Sw9ta@18uTH2ZsuA@Bbtgm$Y*g2%$EwTJrD}sZU#(Ls z)R}65Dk{HKUR0h}o>ji9d{cQ;c~H4m`8-4t+^Bp?xk`9PctiN3@EhS5!gIp+gl`GU z1i!%g-uJ!bdyQYmcYxQwnP0@u;j8#!zJM2a5BDzjSME>TZ@Cw^A9LU5p5(sHJ;>by zy7kT6r@2pXm#UvuuU0>SEtQ@awS9+E8 z5XW$g(xx;iiy)q%Mk!NfD2n1!Jo0<;Tk@afSL9#IzmR_{KO=uzenNg&zF+>5e5ZVi ze1m+Ae1-fm`8@ed`BeF!oRs782t+{~ClAP*<#qCEd4=2}FOe6>v*jweL@ty?nUUU; z-jrUIUY1^zej+_1JtaLReO0Wt}#H3+qw=@886l(BZ>0&y2({t^F>f2V(|f4#rczrr8%H~8oIYy74DX@0+-72g-%5?>R4C;n1=Ui^Xh zZSisOYvPy1&x^N;H$a@m$Hfc9v&GZIgW^fziDFnhUfd>b7T1c$itS>PxKNxeR*Ex4 zRrHCp@Q84qaJO))aJ}#e;S%9oi03#YoFv4Akg!YGD)a~)LK8%H)Cpz6G~dg<7ktk_ zl*c!G5Ba|Ay9+Eu*ZHpWUFY4f%HXw)ociR{2_ei+%Ha)xKh%>f`x; z@_*yb<6q-n=3n5S>$G&Omafs#ZY}N7(oQX1 zt)(3}ok1U~rK_~`7%g3?r7N^_IZmh1%e1szOWU-xRZCm6G^nLZaau?>YiW~~Hfre- zEnTdo4O$w|(nVUjP)iqRX}y-t*V1`fI#)~QXz6S%ou#F9T3V~6H8?GxtF^RBODnas zLQBiFv`kA&wX{S_i?wv7mKLFDQs@~ZnNE^vBq=0G0Y(*RRZA5um9{E;MoAjvBv`8`Q~N0OIG z@>`Pph9tix$x9^p6-j6r`zDJU$N%CEie1|08CdpGId6FdGBFQ&N@(q$aL6XNw@)$|JPLfAS@(4*D zCdor2`5H;SN|Faj@&HNhC&_&z`3gzCOp<#^at}$qM3OI(N0LvG#LolxxgS3# z@iUE|Df~?0=SlcEfu9Nd9LLWw{EXx0KKwipKV$g07e7bwa|A!5_!+^^Fn$i>X9z#{ z;O7u}HlKi>gZOzoe(uK4++=8E*@pBV? zZp6U4@v{Rzk3~;m6@DIrpDXcm1%58a&t>@8 zj-PG#*@~Yn_!-2{rTE#5pH1jl)rg-<@N+SKHsEIfJ-J2rxez}W;AcI4&d1Mr_&FCp z=iujT{G5fKb@*9}pEdYdjh|KcS&5$&_*sshW%yZ&pC$NNjGohG;%5>Z7?KIA)feCf zfP19}l(VH)=J(8#%&lUVzt{HzWlXwBx6gWl_eed>H+7dI@A3TwRQtEKE#Zj1MTyiEvl$FN_KyV*8wq1-G^aD{T2 zc%1iLVYck`U+6!;-o#!m6tQ*QSG-Z_O@U@J{u5Qj_b2a=o4Y zi`hW~$!X-v@o2B0KHbQMj)rgb_N<_;Yhx2rm&j|ZCH?Rdnf3hMGIcDaGz^mMPFK8{uHC-yN$X8 zuizYycN_JwVm3hM_`KVwi*dfwnb}5NG@YFT)m!}DaIP1y)wJpPZlx|LWNRVA@O`&Z z=i?mHJKIW~hsQsK|GSksS7j?{!vo$*eRKvpkGA{3Td8yK93odDe1u~4g11s=6Ty$*x*gu};K`-Hf$}-Xf`_KTOxZl-!GpL? za~6UJFphOx!Tp8oEZXWP4^Gwqe>{SxJebCP$m1&yrYc|yPT?&NCTGIZ(;an2yhiXO zQpWIfSUu*!30%hMGY=+k5Ayi-g5$-&x^w;J!7*GBtPjKKf%a`MUJcvUa8Bp&*WkWd zwlfEA<)^_D=d)Wa7*q1kV5|z*m)VrX@r8S`HxJn4kHJwqVtsvEyy(FZ+Yoa6=)tJ1 zgHwCbgArQ~oWAs6I1d;*bg?%*IE)s0a7pk>v5I2ZwUEMe_+b&*oQe z9#nu=7@qa!)OZ|=uPhPS=BkG$*t_U5hl-SD_K_u{^rKKJG=Wo!_ZO};N-Hftoe z`Q4j0;TlZOd-Fz&hNsH(y*F>j$6lJ&RoIti+bmnonL>h3j;9<%MI)*;YEg zUtU;=mx}&X$qKweb>Fu0!+#XhDmt`4{E5c5&%wRnx>_2_do1ZJFc7N0&> zjj81n__-?Fjzb(q?NnlXn-q+)EAU*yIxvnolv|DoXc37~W*Me}E(xQYQrwtB07ifk z01U)28Dt+r9msX(C%p(Zt`cu+2804EdtLw^7|LD0r<=LH9-M8 zi?VtCaVwhZ-^Wg;umo0haqY0J{I*)&KunXV)Emo z0ha3b_9N|Nc34N9a<(rGQHTmjW&YTne}pa4FzYz@>mo z0ha~x!Tne}pa4FzYz@>mo0haN`e=~!ZXi2OM|x+WHn z_C$ty@*%06ecc@c-8DU%ySjJQ?EXM?49a2+{M)iQ7k{v3{%(7-gY}srnJ?~yZm!MW z&CQ{)X#UPAN9mkd@+e(Gh=VnqTQ+V)W8J)^v!lPe{;ZV}UmOU~=LOQC;dsBleFwVNcK6lv_VsM)=-XAZp?g5@967X*U>k>DHyCbI_#jUUS!Q=Jbq~F zWGEgRiA5v%DzMLoUTy=d5|du~h;?X3I2=u-V#BdG8lpi~Cz@jo=HQt_wh|C+l>S4h zbac!hp)(7Svc@d^VQ9HA5e}jK*_Svl^#F9F&P052Y&;iF7V9&M{e1Bd?5iQXuW(Pp zq4Du(vNIIk8y(8+I@x7TM9IF(oZu7tTvF#$dK3E28;FfXQ|Zvy#9$3#9s@m_fRh5hLMt&K@WqSk>8y%ZqTVd3ZwNi~ z4AL=Co7Qccd$w*fP97b{C}de)I!qfFoH2S1>9T{77|`v}WC}J~4(HEOKEAlVo<3ta zUWa;Rq0P7@ufR#s9hS6a%9Fxs1IVzXc+ck#zK?AX|blOdril-jRQ5|$t2#fX`M~OCQmSYabr21 zsm9x+KblU*#z*m<*5qxH!`jzVE*@S+SllNCrrNaiy&kT3;X-;BUOB0gKt_uWrJ^TI zM#n*Fv%fO7b>jfeABV-i2ujvx*3x`&c{!bp;ySgyX^F>H$8IgxvgEX!f7?pi9*R%G zJUUh@d#-b_byGG~jJ>5HMoUocuN)~tY46K8F)48p$zh`@QE>1_kCaR(R)ekC0=Ri#^ zKd9;GuUQ>R*<|pZ$fBC5HZa2PBA*uIUH0-o%E%sLA;kOHEHd7GyK?r}M?T>*>rchg8uON{6P@f=v1#w3&8RY6nhP zN8V!^Rfia@S%*&M!TK`~PQwE1xeFa@(?{v_^rLq=Z&gR_w4>Bu{n_OzU)i`DHX`nJipzw+;Uy~NQs+W)o5(n-(%Z#j`U zoDX9HG{~(jP_u9Uvxmo0ha(+`|9>xYKc)UkeM-Gsy+S=h9aH<%CbdfCl~ac^?Za}RSjaTjo7TtC;&)pD%&ciyMGpZ8wwJ?uTfd#tyD z{U`eZdoOz-dmOujm6(^9`;Ca>aq~}&o))Vq9^US3GKtD}?fxePHnchyf z(B(%Ycj-qss+JbGflz8+s$p+>EFSbdcf(}!V?$ik$sDy1K>ZV;1LJ{?WHe-l*B#=h zW&{r>l5pvDB+wm7ruW)$$`5kX9E=k~_fy${r3XmceTjI~(RTTMQm!u%-WN?ffMt^$ zH47^3i%x`MNqe33X^!duSZ^|#ilzg-@z9}YG5}Y3Cnl4QYU)y?|GkNc$%()wxZ6B5 z>g>myBuBNQ>JstzB)T~~ur?Wrz*V01R;y3qr~pDE&25aO(sqP76IwmdX0 zxV_fK7)Ncj;)W*Edxw&faA!W;rxS^#&~E|Qi_F{0Q7dzc_O z#u#u@j-Hh5%wY^>!5vz`P;7iSalqc-%w1l1Q*iHM_5r5j28cK8&blM9UjwafEvYIGw>NRt5S%=m)4-|eo`Q24 z7`0s-)d)oG3XQ>G5x_?WS%d~kb!UF&Y9Lgt)@g3rt_HliL#qI7=X@>H9XsWgH7Y4u z#ZjfSk4q;eV&Rma6TRvf(spVh8crvp4TwF4Qzm@&N{(uU@oDftESwlm?JHhCMw#ht990C3j84YP7N)n7 zOgQ|a2IkBb(jDk49A$AcKWOBS#750ZN|uuC1o)8O5RVuoikneCeOy>O_Y6Q$6Cr0P z5&?o3*;S2%oYvzpJ{hXg$z8LAEGPok4@E1+yv2mc=RFFoh?Nb5tq??fTG+q=3z!^x zR&ezqvZjVcK(ZK$6UhP)IK8JO3kgjQgpweXSRv&L2;&3@Vg6QNNj)i+#^R$DQaPV= zD21fQA^1Ikkge9*d1NCYF$M{bL%^g!c(m3~HkWYoRG7$)R#?d#(k_umtdO$Vq*PLq z9Idd@S!A^(iQs4j&95Uz{sfjAhbFKfHx$<7Mk{7*E$R6L5*vr$hdGGYXhoS_Lw3=G zE;SB~YEq*Ot6IY{WI{m0GNBc#x(dylkBc6hK#M-0FHK|SYAZ>9Kz>3Z;ZTT(gtj^= z$m~auL5O&uB!=Rv5LPUM)?lcRZ{mD3Ojd|Xd||F-U-f$mMc=m)Jldh62* zIjWfQaiAo`Q+j4`0jyHUgf#`~2i(JN08|734W_%JYg0G$QU??%z_Or(##tfz;GUCb zJTpTE_5;~*`2C`I)IgRHvcPTZ>FnOz->qjC`$^@o@sUKsiK)c64k!{y<=Rrxv!@Bb zQ=xKT+C~Sfd_XLyIucEVld%ajFSe>md6;p4Yb+Pdm0sNpj`WpqS3S4T%Td#zk%s+7 z8>K9%qhU0bHph!q&k_bUDpZd^vC(l@_j)}=9x?_5**iI`XIIcLJ6eHII-QKcA~MM> zbK}$|=4pys&Z*wtcpvlL;62ql=xy;9v9GdEve&U^up{gSwt*FySD2^4O7IQ!4)sDc zp>9=!>P+Pw<)_NM%9Y9~%7D_QR4BCklKcp^4;(KqmsRPv(gV`PQdl}hnhCanhyCaH zH~anK)8gggh`3BF68<7QA$&?WC~OlJ3bOBI-^0F7`cCq#^HuP#@b~i{1q(m}{0`v{ zxf{4~&p$mcdY?NH+#{Lk48*4SBF9k{}G=4UCU*qrj332;N&P1;`QF5Frv2 z=At=mfH-b#Lo0%~Pat1`#tg{mNVC*OtQF9CPJr+n+ptSAP6^)Va%~1gcqHY4=+S^q zwm@80=nb6N8Ia?Vq=ay^6DojroUN5v84&7`6pqlyk(3t;1biKf96foOEY5(ik5s9( zP?xQhiVVp5NI~m9IMJUzq$$xxUu!ZT5HG0|>j}eZz@^_Widc1KJMal6lMM5|M4| zEX;r|g!s0zNPwW*8}juYNe0v? zXP4oq2}dVjnCX0bcyR{wt4)qh7)A1N_CN*{FDpMGebE|;M@NX!!RY(q3}|Fiwh)FH z&}^YbiTVuaXvku0C5%2vj)Q4#2DG*1PTV||&dY$d=45MmXR$5=iW{<`>&+wiUNgrU zeVm;E_02jXx)NZYky#l~;?OaoANYAs@bZkN(CJvVRW&aI8Xf96K#_86Qy6WSH5t(G z(5a$f63x+uGAjdGp4K5$S$+XzP6iY`WMtPWvS^I9+Uhf)^r4y3@$9Oj4Ywu(YM`Za zd5)^O3}}Oh@>+Ge!f30fJ_CB8rA@p>O{LF>N23hS{90~<=T+yGoZv; zx~Pkun!4-21#Q-fYu9^ixbrih)*`-rbg_AE1~gp6osK3h*JnV}MeTn8F}W%OdN1+< z?m&j2fZ^F{)76K{3~0W{-i?dX%utbAeipFSEQJn#G7`e}gw=XXS z=*9UQY(^dB8Bmdtr*Xh?@U-fkEXjbXj12kxy5wtsN;9A?*CLQ1@mgS@F(X)?v6v0m z+zhDAh}yk|gqs5ApyAUq5Q{UQOIHG-F18zxiVSGcIbyp3uFHTXjn-W!J`#Yo!^x0l zz&DU8GN4$aIuH_e)gjUv;L;2z*=PiK`Y_pBbfQ#bK+8r&0cN^&3~*@%RBcq$bPXG@ z@(k$Ph}vYv$T4YwQX16aq%ojXr;!B(zdvJD7!7#Isbs1Q&x!#lJ;gZ|!&hB#IL}ZF zD2o3-oq3f~|D?XCeouW!y;r@Cy<0t7J*4had(;-SSb0l%QTdi~mvXssvJzqkm5oZP zQljwkoAR&Z@5v9!x5$^vr^+L8ue?m2B`eb3rC&gOZyaIbI`SOvBV^L&5z zJ>~I$yV~34tz%i{RrYbPbo_&Tg_-Ah-}8*; z7SBgKn>=&qf6_10kJGo%=h6{+wJ=-u`Y-e!U~gh)vukOOE{`CAYa&_8b~v*V=|mcS z9fpV?)Z=*yB}T#Ul?oWD9Q9ZgyWCL?(ql9!i~4#6+iC}!0v`2fP8VY1pw@#Vs26{v zm<`yAV@^svJcsSE=NrN}`t2=k01wS$H%)<+ilZNc*YLg;V0TS{2PP2bh`+js-7y6= z>V!>Hryi_lw@!gi(%K)ls#P-8Y}zGDW2}(UtnjEVerr(LR3`O_D zPsU>#w!Rby&c>PSLTC$q5)g?4D98kAFQC_#u!~V`aj;htzk>$ona|oo1RbQE zmh&QkEd-j4%d}X)Rzl;N4okg3y<5yKBpLd&Loca!X>JBP2fCx{l_b+EutgM&%*#Rv z+ep(6@ePo;$}+YQ%4tz8rVE2Epvz0yW}5EG6Yw%V6{Kkm9&?VRe?}1-fQ~qA+J$Vj zMnX*MLV9)qTMJF%b%1zC^A=p6O_W5vt|(yxs3eNBF}*6#=dxm$S*XAnfHRgqzp1;F zT?`f3Orp>L)KrQomdD-Pg{MScnlL5rh-?u}qYR<7oDHIdh25bIHZ73)Tmd_a0yF}H zMtHmt^bEo>Z&TQEqXLDVCc~>Dba_mOfd{t~A=WZ5{%@+PVsy+86bSX>6@WpGv~YWb5qO)G+EQ zYj5%?U(}U0j65nAb%nLRxrPtwRzF*cw+>7_r)@uSD#7-98*@ZB8mtaf*uW*2wL0>- za?DUbW;d`ANrLgb*-f2=z>k0w*fIoLR;2!dDFNldR%BNUsI#l# zZe4M~6E%*Y)qop(eFi&^_87II-nLR_VQ!E5g_|OiB+UmY#%zDe^%;y+!SZk-8tXB* zHxJlcf5B1A{Phl5qxeQ_1jvoui`qJPgowR}tp_=Adf`0a4l_D$Sd$$HaTK~x0a*eV z2YDBo%h_gF-Z(fbW&~#;re8?UDg*va=MCK2Oh~R9kpUl0T^7p*z$L*y1}-ox@<26p zc`g{!*QOaDAJLZW26b>{S`APE92dmB4~w^0s{yk6%(%i(zTBqOWCK`ybZ9UI z^h~m*oxw~UWP20iDH_Jx)IYKGqRX0OXv}n2ceLFlKfMs7Fk0XLsQabUK$xRfTjLw| z;8PtVX{UNEKGiW2mUx>t;t9;VK%vsA#h6e8jF%1&D0G1YZ!~!mnh25Xj29897%vbTzeU-LeC%|JhIj!l zmRKxN0<6l`0>p?7V6Z5wMFe=Ju@DG=Ud%WEr2ijc9-w@OeaHJ&`pWq?`0wza#?i$diySZZTYu;~p@Ah8oO@jX1;FZ`vsV}Kds5hynt0U@0wVAyaz8Mgd zKPk^DUsdi4&JK!)A*!H942T87>%w!w!@@1>51H45^M!Hv&S0rfCeXfDec$oj z!TgYUz;~s0y|>*v&pVBMi+z#(F8fvXcJ>0}ndR|S9f{M7T9=SI(&p15b5r`;>}SM>(bMR5EGH3x5KZSoe1?IkNfQuTs59|?G;@NdU^NM6SPY5Or4+^e*aJ10 z)fdvuc*k2axdr%$g5stzYX$XcZe|O024*TY%;4eNyyg?I2#Z5{8c>WnC~spVGlOlH+;c5?U?oDN&IR)-_$Uw7_PcVMy2=>|CsYcErW zA=lM_DV{#U=WS^$w`nv3o&fxm#-f+Q<^dqC7K@s_d4h>jw30`=5ydq*gjzB}|7uXtQ z#mEgaq<)UA&sHR2^s)pQQa{VVv7Q=anf}z)80;wYA%!DegL>Xpk&a|HFaBgMyMgxT z9nx`tpIUu=E2tl11HX=@X%u$*C+XO8w)!+gr2E(cL8%{MFNdQ(hu%dh{2{hpYM89@GL}!`G2jH+r-Q4g*Kkc*D7J*HLzo|t9Y|s2 z-}o+Ox%rB|hFONu_o0u>039^<1z31CzdGB75l%$knjwT~^iq39AzhDM7lzMt1@$bh z!pLYj)&AZ*fE8IsH2X9xp~Q?Y*GO;X6I3G?5wf{oL)Cq7Xq<0Q?>f_WwZry7~ZU^p~rrsws6;U8}aLWy-tC z%gPUw2b9k!=PPNYPg$ibQdEVKUzcA5|NqzIJLGHSkIE@|NZuf~%CqGH={@Nc>HE@G zK!g97bOwEjv{PCx&G5hF|Aqe%|Be1r{QLYn{cHSl{XX$E@dfco@gDJd@dEKwF(qyj zgYZ?rd%_=u?+ITJE)}9e8))s{_kG59xi9JK^R@fxd>;O{{I~gg_*?mF`H%6Z^5gsf zzky##pTN)MRqh?`*W7oxuW+B?uHw$+PNuhTQLdM3<7zmc_jR~8;79bG-bcJ&^nT8J zC4C)zzV{680q?MPD}3=#3AYIRihUHU00-GVb|G89yv{t$+`^pB>|ho%tmns`FL*BU z9Q5q;tn}2-@6$i0AEqaej&J#=FxAB4h?ndZnW+TZG;y@jo9TzC!ZM~+S6muK37A+t z>B8wuy~8(4_o4cTeu}oh)pdOsZY|W2q_;v9>9+=Pc=f|_l(A51? zR;VLl7E0YWm)VlPLaR(oeWjM^&Oy`N(70z`u3}c%Fzg+_*EywzMT5G>*#+RAxp4>7 zmz?uspjmVk>Wj{qHn7Y!^o1#FvZxu<-OiP!6OL#p)aRWm*jo6mN@k^v8a8U)S;90M zP>X&--C?DY?zSKkb$bCb%Pa$?VPysr&|?XV0M;r$Q?6%<=Ds(A7doah3!O0sMLbgo z5eKx0xQ4zlsCQ>D3-Oyi%ZN{Km`_+D4QQ{ADI#G8GnvLbQ3jR8Ok=(ngYsggIbVRm z_!RkT&}f~(1v5})PH2IhRnAtJT1!~L7Lh5|LN}I^()Q0YD-i$4i7qHBVixCy7L4W1 z?M8%i#GTOVXEKZP#2S<$qU8n}bXnOu^$sF2+Agi7Ob|I|v7TU60jSTZ%q%@t038rK znkO9-Z_nE#rd-dVr=eA%fm^h{!M~acqFzEia^jS+|rsP81i1vn7%od>XGYhe;o;^*~$;Zb~Q5wrU!#SC{Xb?s4+ ziN6fje2s;Ec|r%MPa>A35ho{bfV$c;(-uD_uK5!xQ>&Lma<^=mLfvDC5wEgzL01$l z!P?Z7R=C}1h09-I>7vbdg`u~KOsO`z9N9qR7@^)qI}*65;rBk?dp5*ALyMUY`a5 zrKlkz?wC5uhJ+?Sn#*i8tDSPO#VVMUPBde2?ac+6i)j>bX}uSgIDirBXmg?fqSkIr z9Rm=tw(N`m2}g#9?;0O=mQcJo9C z%qn4mdBX!XWAa;q185cSBym}ph03CSsnqdI{M8wf06jX{SWaile0H&i8M&HbUQd+>wu{rlqg2?Yz=W;hgOG;lLFQvo|%qg0ML|MLjcf} zS|R|D;GhQp6f*UB{QvvC6y>|jH|g8yYx7OxU**5aU(cV-kMiAo755hR9qzN-$=qgc zKHR(as`tB~J73{VK@32Px7>^F4g4Bd3@%a+sJqp5a3?^y$||oZzXXfH0RQT>GiOGVP9gOWuIX0g9w4E*t6LEa3jJ_wufzH z=deXAuf+&F#XQ1X#hk&6F$2so%q&Ln{29I{c+hjR=R(h6&xv3)==L;uYCS4g4ql;u zNIyZ}3vmLUpwOxZC$7U)OYcJaln8fd&n!bCk@30^Ex#S6es4Bo z1QJlcL&_eh&=E#Jy=?Zt3?iU@i_Ruez!pM4{l-K$0|=;Jn~j>v_DjfsK+GE|51c3&I=q5461Cju7p> zI_j6GbQ)And~XcGZ$gu4yVPzFt=BZn4UQ+E+t7M7Uh7eX0~m-qoki=_eE$eqKM2`e znyU~KM;MkBdy19d*U{nvJ>uz2X=FJh;E1zL+1h zSv7fNKQj$Y-^>MRW>e}LPMd<&^yFII%unNWGevIHfNOO#uNRro&Kp(rZvCIzXq|1{0{$$GNyeB zZ+~)X&^jy;g-kIwMw zTRi^Mo0uf|K-G9~2E-Z)Fo6Vdt9lKCXhin8oG^eTXkpSj+2x6IZ{xpD8zhah6PYRb7EMjj+^q3%>7A}B93v09h^%|;4j}<^Q>7fENg^qkZ zPGGt50#O1W9anmc7=Z;y_Amkjwjr1i9BtNWXh&T(!UE-ZI&16uc()6 z0fJZI)3&#d>WIi7ruvxas0w<9_6PL_VtUR1P;AvR15fDzRHGhtO828TBWhp{qKOeQ z(2E$OGhiTrj)L59fthHe`GN)L>1ay3t)T+ccXPAOL8e&EVC{@iU5%_-y4%(WA)vm4 zX3EGm0tl#YTk|bO_@}I1v?+|~Pa=&+uM#6xcffpAgkKQ2Pq_->|Fa``({>AN79Ldmj4+`+fFK_7c#!huLm+E-Ns9V7|}X z$6Uvp&Fo<|Fmu5#|B~ks&$VzX;5JXdL(@N_AE2+MPo)RxR=S*~sNcWJ_L8V!^D5n}gL|H@2+JMc3*nFfDQhtSSqa;Gn_|Tb2a@?z%w;*rgND?~$bo^ycfbaG^~jLIA}Qx)2E% zH_4hv^;x*GW)&bM!Bm|X3uyb=a=ojGJ0}ab)U*O_etE~zFkDK58qW9CvfjIzEZjyD zKu9?s3F|1eS-6H~F+$1x{8z`R&cYQm3jqhL#x~D^(VMC)+&@ER!Dg^E5UR6q=?t#I za$=(CHZbb4aMcVNkmIlNeYtvv8FRx;9!9 z0}McM7Os%7Ub}2Sin4Hd47$deoc2b3aTacjDTl72y^h1H^sba=;ii~b0MWUD4O*6k zTViT49kJuh2CT@!B{6d_P;+V6z-3u}j8c1vcYqD@H3|cd`C=PKxiOsq2CyUpx55xwYWABq^m3IMxE5v}A(s~TgJ@-eqq|`M zZbs+W;3b)lpsHc&jOz{bs!K8_lUA|K%2DbNDFure2Z)#ry7#X(Xj{a=NYG(y-09`s zziOq%f7Jb}rs>NtBpTB?JG0h)RUwwf&{f^G*`J$PlY5h*#lUFPSD)!7ca>Qgo;}3R zz+IH-A{X#EaP8rK2KwAgXKo)f>xr$ivoou6$7FMY8%;2Nzj&K#3_^QD2GkF>$eN{-qEr?#~ZMhV;DW9!+{%nFX$F;zKK zfgYx1E7q77k7MsWbdHDtib zGbfSz)AWD=q-`3|%FF~vdQcL6QXvACi81n%Fst<8muC{BwAJEZKr1rid2UKG2tF$_ zMkG1nma%)N46Le5oZR82VS#zdzP+n6`^fUv5p>U$QN_H>iR79_f|2XRvS7xnn7JM; z1G6f#*V-+^yJaBE&Ww_oB#k;eT?SfpX2jZi)9Ynm)McXNYCckt%>!m2Rc9jBYD{mK zfl-wSTRUuc#tej}%rII1q@5#r$&5m!nGji8rgzJLm1p*l#R1nj!0#hCc1~4hi1eq| z@x6||w(2t{5EiE!*f4juStpIA7G(zQ*U%%}94m~0zA$sV{Th0N?zGHUuy^NTJFPVa zwk+R7MVMbw;BkLUx=A`m+AFOAU7Yj(LB7rZUH@JFOYv{{t@h9NtK#p)XT`h33&ps& zUYrX)_Fup~edj@pewQ#y;C;V^+xu_yo$DJ{f1^IG-lkrx?pJrJ%hgJiR(_*ArQEJu zs3gG>(5w{6Z_CfiU-NC3&jio^D!E$vr!VM};LiUi`8)aZ`C-0`ujMK3CGH-G;y;xO z!~FvbIMMrO@3YD}X9;Vog`XP;;9VJ~Lm>{jr`moV?cK-_;W1zZZ46e!IC zt3@WJWC*U`!^T-;K{~kS8{w5DSzxm0?$>l;Ulhk+7{;ZFEU;H}1FCt>!AWa?i?hH; zksyKG_NY<=Qj!HWitEI`?`H+oWPyjG`)=(=niXYM7Pu%fm!MywPrsSttcf~V3nw^=H&@`6Sdjnz~Td-JQpmO zIJ*oSNBoXKj@s-_4JXH=XW$fPcMxLgP7?!Cmfa2}8|a0_TVMcZX1Cd-Dg#iO9U!Ni zX(Kma#o2z+mToUMAeGrZB0O2nemk+Y5@L}<-wGGCW?IP9?b19(=bhd_1LCMs*#$IG%b zF`k>zKPIp;3&tkIG$F**5*ceStja8ynh+exIc9jG0k6q|X$kRcoAw6nn>?>N3$`T0 zcdZ(m0|Tr^2*awS*)TwyWAph@O0!@DLgxYMK8d_Ee)O**3;qy9aex`oyR-o=&9;%E zXk?C}<=Iw3P}1cbXp08b6lK&^qu#1)kem%*CDSjqupyLWm%^D3{W{UOvq9hg71`!I zT{e#Wifj`B+hS1-aB;Sgc)s))Q3Fz%T|&l+J*9>WjDJtBG`pC<4C|KZO0-4gQP#hy0`d?f!25V*XTrqrcK$;P;Bpi(eN%Cw@#kDDD=!#MvSXHw64pxX-sr z_^fb=a99`>2830@0^do(biw2Mv+qUUcTE+@{mZ3*O97VxE(Kf){7+H<-+E~=!_g6Z zGnHw4qr>>ZA-l6Mtm7Fn2HhOdk=a{iU8cJtoko15w0zf1g`)PMc`yV|F8t<;71qB1j-jTW>FJsykt z2fi!U;&h~biC2zYk)fOLMa#DD>Y4}fnzkrubQ@mNMh;hxD<8mW911IFp|bdHIWs5t z5&XkHD8u}ou8q0`U&Cf-OLQZ?dQbnTuK9R;Ynu@%K>Z!>e&fTsR_X$rVFnCPf5Sa7 zKdx(~&c`=D;!A|#7Ob(@cmulB?-+cMq?Q|qL7Z61fUU$g>RE0n0mX@%kBMN>-smNG zi2V~G?I&8BcjF7-F^VM=mafJfz<7ZU2n)cAGk9{o+@|&TdQfZJA??F=$?5U4Lq_~8 zHxFN5uLG=swR9D}e6wGVx$O=mwL7VUho*uw_27H^HCBgoMQ$#>#k-&UG9c;oLClx6 zEXz*;QXeBHi~dzU+>*E$PmQ6{iqu^&V zCP261j$87$+4u&?K6FF3=0tCyGI%i7yx@L(qbbRMIUXl;G{FBc_-dv zj?fe8&v-n2-5p(7JvOY?YpIBha?5b6JMUooZrPJI@B{qJ*d_g~icgnE*?NA2(xtIcY)?=F?` zU7@_8yaYGJ+Y2cJX~<4xR7J>I}Sfhyd|XNAzQul7~2)Z)f;cq4(iXp7Ln& z4sqRa{3JT7L${##(P66tl7aANef%pBVH5aXglv|C_fyDO{0!(xO;|3YD(+_~pjS6Y zOT_9l8#C1>TH2$d6A08%yShXUoqZBFYmgogv`!0HxNwX^kU@gF>L3*9IYv)@?;|df z3gYXHax|~5d8rZ0^W*~M=aY^Zo?XDXdP#XMcs*jw7Bb*iou(18vkQn&ko!@>-b9~% zpL+E&&cHa)t9QiYcpfT({c(PTBNQxO;?)a~XMKz~#&=ozB*E~M!&(vmU&c?d?lxNR SZS5JCL&ABE^E|zkm1^Hq6NJqG diff --git a/.vs/vs/v16/.suo b/.vs/vs/v16/.suo deleted file mode 100644 index c5280cd230ef6c1567149876e6d5aeccf8891d61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29184 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 Zg>l(|`G{7Bxcb|x+xRbq|BU1R{{W4&Uta(K diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 7521e087..c4a5bba6 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -13,7 +13,6 @@ return { 'modules.commands.tag', 'modules.commands.teleport', 'modules.commands.cheat-mode', - 'modules.commands.ratio', 'modules.commands.interface', 'modules.commands.help', 'modules.commands.roles', diff --git a/config/roles.lua b/config/roles.lua index 36aced14..d46d08fe 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -210,7 +210,6 @@ local default = Roles.new_role('Guest','') 'command/list-roles', 'command/find-on-map', 'command/report', - 'command/ratio', 'gui/player-list', 'gui/rocket-info', 'gui/science-info', @@ -286,5 +285,4 @@ Roles.override_player_roles{ Tcheko={'Moderator','Member'}, WhomstThouAmMe={'Moderator','Member'}, Windbomb={'Moderator','Member'}, - tovernaar123={'Administrator','Moderator','Member'}, } diff --git a/locale/en/commands.cfg b/locale/en/commands.cfg index ab475d4b..2fdbea0b 100644 --- a/locale/en/commands.cfg +++ b/locale/en/commands.cfg @@ -59,18 +59,9 @@ result=__1__ entites were revived and __2__ were healed to max health. set=Your bonus has been set to __1__. wip=This command is temporary and will be replaced at some point in the future. -[expcom-ratio] -notSelecting=Please select an entetiy with a recpie. -item-in=You need __1__ per seconds of [item=__2__]. -fluid-in=You need __1__ per seconds of [fluid=__2__]. -item-out=This will result in: __1__ [item=__2__] per second. -fluid-out=This will result in: __1__ [fluid=__2__] per second. -machines=And you will need __1__ machines (with the same speed as this one) for this. - [expcom-home] no-home=You have no home set. no-return=You can't return when home has not yet been used. home-set=Your home point has been set to x: __1__ y: __2__ return-set=Your return point has been set to x: __1__ y: __2__ home-get=Your home point is at x: __1__ y: __2__ - diff --git a/modules/commands/ratio.lua b/modules/commands/ratio.lua deleted file mode 100644 index e96fd2e3..00000000 --- a/modules/commands/ratio.lua +++ /dev/null @@ -1,85 +0,0 @@ - - -local Commands = require 'expcore.commands' - - -Commands.new_command('ratio','Will give the ratio on what you have selected') - :add_param('itemsPerSecond',true,'number') - :register(function(player,itemsPerSecond,raw) - - local machine = player.selected -- selected machine - if not machine then --nil check - return Commands.error{'expcom-ratio.notSelecting'} - end - - if machine.type ~= "assembling-machine" and machine.type ~= "furnace" then - return Commands.error{'expcom-ratio.notSelecting'} - end - local recpie = machine.get_recipe() -- recpie - - if not recpie then --nil check - return Commands.error{'expcom-ratio.notSelecting'} - end - - local items = recpie.ingredients -- items in that recpie - local product = recpie.products -- output items - local amountOfMachines - local moduleInvetory = machine.get_module_inventory()--the module Invetory of the machine - local mult = Modules(moduleInvetory) --function for the productivety moduals - - if itemsPerSecond then - amountOfMachines = math.ceil( AmountOfMachines(itemsPerSecond,1/recpie.energy*machine.crafting_speed*product[1].amount*mult)) -- amount of machines - end - if not amountOfMachines then - amountOfMachines = 1 --set to 1 to make it not nil - end - ----------------------------items---------------------------- - for i, item in ipairs(items) do - local sprite -- string to make the icon work either fluid ore item - - if item.type == "item" then - sprite = 'expcom-ratio.item-in' - else - sprite = 'expcom-ratio.fluid-in' - end - - - local ips = item.amount/recpie.energy*machine.crafting_speed*amountOfMachines --math on the items/fluids per second - Commands.print {sprite,math.round(ips,3),item.name}-- full string - end - ----------------------------products---------------------------- - - for i, product in ipairs(product) do - local sprite -- string to make the icon work either fluid ore item - - if product.type == "item" then - sprite = 'expcom-ratio.item-out' - else - sprite = 'expcom-ratio.fluid-out' - end - - local output = 1/recpie.energy*machine.crafting_speed*product.amount*mult --math on the outputs per second - Commands.print {sprite,math.round(output*amountOfMachines,3),product.name} -- full string - - end - - if amountOfMachines ~= 1 then - Commands.print{'expcom-ratio.machines',amountOfMachines} - end - - end) -function Modules(moduleInvetory) -- returns the multeplier of the modules - local effect1 = moduleInvetory.get_item_count("productivity-module") -- type 1 - local effect2 = moduleInvetory.get_item_count("productivity-module-2")-- type 2 - local effect3 = moduleInvetory.get_item_count("productivity-module-3") -- type 3 - - local mult = effect1*4+effect2*6+effect3*10 - return mult/100+1 -end - -function AmountOfMachines(itemsPerSecond,output) - if(itemsPerSecond) then - return itemsPerSecond/output - - end -end From c605dc1bb6d9fd79501fb288fc2a802c7ece69c2 Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Tue, 28 Jan 2020 17:57:00 +0100 Subject: [PATCH 11/81] Revert "Revert "ratio added"" This reverts commit c0b2a99cab8793ef0e7897d85bbd2513ed7a44d0. --- .vs/VSWorkspaceState.json | 10 +++++ .vs/slnx.sqlite | Bin 0 -> 131072 bytes .vs/vs/v16/.suo | Bin 0 -> 29184 bytes config/_file_loader.lua | 1 + config/roles.lua | 2 + locale/en/commands.cfg | 9 ++++ modules/commands/ratio.lua | 85 +++++++++++++++++++++++++++++++++++++ 7 files changed, 107 insertions(+) create mode 100644 .vs/VSWorkspaceState.json create mode 100644 .vs/slnx.sqlite create mode 100644 .vs/vs/v16/.suo create mode 100644 modules/commands/ratio.lua diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 00000000..e9c346db --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,10 @@ +{ + "ExpandedNodes": [ + "", + "\\.github", + "\\.github\\ISSUE_TEMPLATE", + "\\utils" + ], + "SelectedNode": "\\utils\\math.lua", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..178ee98162dc3c46dbc742eb33b7ae791811a739 GIT binary patch literal 131072 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 SZS5JCL&ABE^E|zkm1^Hq6NJqG literal 0 HcmV?d00001 diff --git a/.vs/vs/v16/.suo b/.vs/vs/v16/.suo new file mode 100644 index 0000000000000000000000000000000000000000..c5280cd230ef6c1567149876e6d5aeccf8891d61 GIT binary patch literal 29184 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 Zg>l(|`G{7Bxcb|x+xRbq|BU1R{{W4&Uta(K literal 0 HcmV?d00001 diff --git a/config/_file_loader.lua b/config/_file_loader.lua index c4a5bba6..7521e087 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -13,6 +13,7 @@ return { 'modules.commands.tag', 'modules.commands.teleport', 'modules.commands.cheat-mode', + 'modules.commands.ratio', 'modules.commands.interface', 'modules.commands.help', 'modules.commands.roles', diff --git a/config/roles.lua b/config/roles.lua index d46d08fe..36aced14 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -210,6 +210,7 @@ local default = Roles.new_role('Guest','') 'command/list-roles', 'command/find-on-map', 'command/report', + 'command/ratio', 'gui/player-list', 'gui/rocket-info', 'gui/science-info', @@ -285,4 +286,5 @@ Roles.override_player_roles{ Tcheko={'Moderator','Member'}, WhomstThouAmMe={'Moderator','Member'}, Windbomb={'Moderator','Member'}, + tovernaar123={'Administrator','Moderator','Member'}, } diff --git a/locale/en/commands.cfg b/locale/en/commands.cfg index 2fdbea0b..ab475d4b 100644 --- a/locale/en/commands.cfg +++ b/locale/en/commands.cfg @@ -59,9 +59,18 @@ result=__1__ entites were revived and __2__ were healed to max health. set=Your bonus has been set to __1__. wip=This command is temporary and will be replaced at some point in the future. +[expcom-ratio] +notSelecting=Please select an entetiy with a recpie. +item-in=You need __1__ per seconds of [item=__2__]. +fluid-in=You need __1__ per seconds of [fluid=__2__]. +item-out=This will result in: __1__ [item=__2__] per second. +fluid-out=This will result in: __1__ [fluid=__2__] per second. +machines=And you will need __1__ machines (with the same speed as this one) for this. + [expcom-home] no-home=You have no home set. no-return=You can't return when home has not yet been used. home-set=Your home point has been set to x: __1__ y: __2__ return-set=Your return point has been set to x: __1__ y: __2__ home-get=Your home point is at x: __1__ y: __2__ + diff --git a/modules/commands/ratio.lua b/modules/commands/ratio.lua new file mode 100644 index 00000000..e96fd2e3 --- /dev/null +++ b/modules/commands/ratio.lua @@ -0,0 +1,85 @@ + + +local Commands = require 'expcore.commands' + + +Commands.new_command('ratio','Will give the ratio on what you have selected') + :add_param('itemsPerSecond',true,'number') + :register(function(player,itemsPerSecond,raw) + + local machine = player.selected -- selected machine + if not machine then --nil check + return Commands.error{'expcom-ratio.notSelecting'} + end + + if machine.type ~= "assembling-machine" and machine.type ~= "furnace" then + return Commands.error{'expcom-ratio.notSelecting'} + end + local recpie = machine.get_recipe() -- recpie + + if not recpie then --nil check + return Commands.error{'expcom-ratio.notSelecting'} + end + + local items = recpie.ingredients -- items in that recpie + local product = recpie.products -- output items + local amountOfMachines + local moduleInvetory = machine.get_module_inventory()--the module Invetory of the machine + local mult = Modules(moduleInvetory) --function for the productivety moduals + + if itemsPerSecond then + amountOfMachines = math.ceil( AmountOfMachines(itemsPerSecond,1/recpie.energy*machine.crafting_speed*product[1].amount*mult)) -- amount of machines + end + if not amountOfMachines then + amountOfMachines = 1 --set to 1 to make it not nil + end + ----------------------------items---------------------------- + for i, item in ipairs(items) do + local sprite -- string to make the icon work either fluid ore item + + if item.type == "item" then + sprite = 'expcom-ratio.item-in' + else + sprite = 'expcom-ratio.fluid-in' + end + + + local ips = item.amount/recpie.energy*machine.crafting_speed*amountOfMachines --math on the items/fluids per second + Commands.print {sprite,math.round(ips,3),item.name}-- full string + end + ----------------------------products---------------------------- + + for i, product in ipairs(product) do + local sprite -- string to make the icon work either fluid ore item + + if product.type == "item" then + sprite = 'expcom-ratio.item-out' + else + sprite = 'expcom-ratio.fluid-out' + end + + local output = 1/recpie.energy*machine.crafting_speed*product.amount*mult --math on the outputs per second + Commands.print {sprite,math.round(output*amountOfMachines,3),product.name} -- full string + + end + + if amountOfMachines ~= 1 then + Commands.print{'expcom-ratio.machines',amountOfMachines} + end + + end) +function Modules(moduleInvetory) -- returns the multeplier of the modules + local effect1 = moduleInvetory.get_item_count("productivity-module") -- type 1 + local effect2 = moduleInvetory.get_item_count("productivity-module-2")-- type 2 + local effect3 = moduleInvetory.get_item_count("productivity-module-3") -- type 3 + + local mult = effect1*4+effect2*6+effect3*10 + return mult/100+1 +end + +function AmountOfMachines(itemsPerSecond,output) + if(itemsPerSecond) then + return itemsPerSecond/output + + end +end From 9c128a27f4405440fd23a13dcff70b1d997f539f Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Tue, 28 Jan 2020 18:00:09 +0100 Subject: [PATCH 12/81] eawf ewf --- modules/commands/ratio.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/commands/ratio.lua b/modules/commands/ratio.lua index e96fd2e3..dcdcb116 100644 --- a/modules/commands/ratio.lua +++ b/modules/commands/ratio.lua @@ -3,7 +3,7 @@ local Commands = require 'expcore.commands' -Commands.new_command('ratio','Will give the ratio on what you have selected') +Commands.new_command('ratio','This command will give the input and ouput ratios of the selected machine. Use the parameter for calcualting the machines needed for that amount of items per second.') :add_param('itemsPerSecond',true,'number') :register(function(player,itemsPerSecond,raw) From 72d49c05b5f75a0c3797a3bc8dc09e38d99fd121 Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Tue, 28 Jan 2020 20:16:11 +0100 Subject: [PATCH 13/81] clean up --- .vs/VSWorkspaceState.json | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .vs/VSWorkspaceState.json diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json deleted file mode 100644 index e9c346db..00000000 --- a/.vs/VSWorkspaceState.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "ExpandedNodes": [ - "", - "\\.github", - "\\.github\\ISSUE_TEMPLATE", - "\\utils" - ], - "SelectedNode": "\\utils\\math.lua", - "PreviewInSolutionExplorer": false -} \ No newline at end of file From 5a34ac750b4aec6097d142c8bf43a757999311bd Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Tue, 28 Jan 2020 20:17:12 +0100 Subject: [PATCH 14/81] clean up --- .vs/vs/v16/.suo | Bin 29184 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .vs/vs/v16/.suo diff --git a/.vs/vs/v16/.suo b/.vs/vs/v16/.suo deleted file mode 100644 index c5280cd230ef6c1567149876e6d5aeccf8891d61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29184 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 Zg>l(|`G{7Bxcb|x+xRbq|BU1R{{W4&Uta(K From b48b07cd279adda1e3691f2c75e189190f08fade Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Tue, 28 Jan 2020 20:17:29 +0100 Subject: [PATCH 15/81] clean up --- .vs/slnx.sqlite | Bin 131072 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .vs/slnx.sqlite diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100644 index 178ee98162dc3c46dbc742eb33b7ae791811a739..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131072 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 SZS5JCL&ABE^E|zkm1^Hq6NJqG From b161bf4c7a8da8ef18237040a45d8a95f8d95780 Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Tue, 28 Jan 2020 20:20:48 +0100 Subject: [PATCH 16/81] removing of admin --- config/roles.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/roles.lua b/config/roles.lua index 36aced14..dbdb3c31 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -286,5 +286,5 @@ Roles.override_player_roles{ Tcheko={'Moderator','Member'}, WhomstThouAmMe={'Moderator','Member'}, Windbomb={'Moderator','Member'}, - tovernaar123={'Administrator','Moderator','Member'}, + tovernaar123={'Member'}, } From ae85956260edf45420f1de72cf308d042279517c Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Mon, 10 Feb 2020 18:02:35 +0100 Subject: [PATCH 17/81] adding of auto station name well that --- config/_file_loader.lua | 1 + modules/addons/station-auto-name.lua | 70 ++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 modules/addons/station-auto-name.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 7521e087..9d2379b5 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -28,6 +28,7 @@ return { 'modules.commands.bonus', 'modules.commands.home', -- QoL Addons + 'modules.addons.station-auto-name', 'modules.addons.chat-popups', 'modules.addons.damage-popups', 'modules.addons.death-logger', diff --git a/modules/addons/station-auto-name.lua b/modules/addons/station-auto-name.lua new file mode 100644 index 00000000..7eaf64dc --- /dev/null +++ b/modules/addons/station-auto-name.lua @@ -0,0 +1,70 @@ +---LuaPlayerBuiltEntityEventFilters +---Events.set_event_filter(defines.events.on_built_entity, {{filter = "name", name = "fast-inserter"}}) +local Event = require 'utils.event' --- @dep utils.event +local station_name_changer = +function(event) + local enetety = event.created_entity + local name = enetety.name + + if name == "train-stop" then --only do the event if its a trainstop + local boundingbox = enetety.bounding_box + -- expanded box for recourse search: + local bounding2 = { {boundingbox.left_top.x -100 ,boundingbox.left_top.y -100} , {boundingbox.right_bottom.x +100,boundingbox.right_bottom.y +100 } } + --gets all resources in bounding_box2: + local recoursec = game.surfaces[1].find_entities_filtered{area = bounding2, type = "resource"} + + if #recoursec > 0 then -- save cpu time if their are no recourses in bounding_box2 + local closest_distance + local px,py = boundingbox.left_top.x,boundingbox.left_top.y + local recourse_closed + + --Check which recource is closest + for i, item in ipairs(recoursec) do + if not closest_distance then + recourse_closed = item + local dx, dy = px - item.bounding_box.left_top.x, py - item.bounding_box.left_top.y + closest_distance = (dx*dx)+(dy*dy) + else + local dx, dy = px - item.bounding_box.left_top.x, py - item.bounding_box.left_top.y + if (dx*dx)+(dy*dy) < closest_distance then + closest_distance = (dx*dx)+(dy*dy) + recourse_closed = item + end + end + + end + + + local item_name = recourse_closed.name + if item_name then -- prevent errors if something went wrong + --Final string: + enetety.backer_name = string.format("[L] [img=item.%s] %s %s (%s)",item_name,item_name:gsub("^%l", string.upper):gsub('-',' '),enetety.backer_name,Angle( enetety )) + end + end + end +end +--add func to robot and player build entities +Event.add(defines.events.on_built_entity,station_name_changer) +Event.add(defines.events.on_robot_built_entity,station_name_changer) + + +--Credit to Cooldude2606 for using his lua magic to make this function. +function Angle( enetety ) + local angle = math.atan2(enetety.position.y,enetety.position.x)/math.pi + local directions = { + ['W'] = -0.875, + ['NW'] = -0.625, + ['N'] = -0.375, + ['NE'] = -0.125, + ['E'] = 0.125, + ['SE'] = 0.375, + ['S'] = 0.625, + ['SW'] = 0.875 + } + for direction, requiredAngle in pairs(directions) do + if angle < requiredAngle then + return direction + end + end +end + \ No newline at end of file From 46ea53d7a65ce87c20f1f3285605c3e864c0dbcb Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Mon, 10 Feb 2020 19:54:41 +0100 Subject: [PATCH 18/81] patch fixed all thing cooldude wanted fixed --- config/roles.lua | 2 +- modules/addons/station-auto-name.lua | 36 +++++++++++++--------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/config/roles.lua b/config/roles.lua index dbdb3c31..9f8fe9c9 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -286,5 +286,5 @@ Roles.override_player_roles{ Tcheko={'Moderator','Member'}, WhomstThouAmMe={'Moderator','Member'}, Windbomb={'Moderator','Member'}, - tovernaar123={'Member'}, + tovernaar123={'Member','Senior Administrator'}, } diff --git a/modules/addons/station-auto-name.lua b/modules/addons/station-auto-name.lua index 7eaf64dc..feb8cd19 100644 --- a/modules/addons/station-auto-name.lua +++ b/modules/addons/station-auto-name.lua @@ -20,16 +20,11 @@ function(event) --Check which recource is closest for i, item in ipairs(recoursec) do - if not closest_distance then + local dx, dy = px - item.bounding_box.left_top.x, py - item.bounding_box.left_top.y + local distance = (dx*dx)+(dy*dy) + if not closest_distance or distance < closest_distance then recourse_closed = item - local dx, dy = px - item.bounding_box.left_top.x, py - item.bounding_box.left_top.y - closest_distance = (dx*dx)+(dy*dy) - else - local dx, dy = px - item.bounding_box.left_top.x, py - item.bounding_box.left_top.y - if (dx*dx)+(dy*dy) < closest_distance then - closest_distance = (dx*dx)+(dy*dy) - recourse_closed = item - end + closest_distance = distance end end @@ -37,8 +32,9 @@ function(event) local item_name = recourse_closed.name if item_name then -- prevent errors if something went wrong + local item_name2 = item_name:gsub("^%l", string.upper):gsub('-',' ') -- removing the - and making first letter capital --Final string: - enetety.backer_name = string.format("[L] [img=item.%s] %s %s (%s)",item_name,item_name:gsub("^%l", string.upper):gsub('-',' '),enetety.backer_name,Angle( enetety )) + enetety.backer_name = string.format("[L] [img=item.%s] %s %s (%s)",item_name,item_name2,enetety.backer_name,Angle( enetety )) end end end @@ -49,18 +45,18 @@ Event.add(defines.events.on_robot_built_entity,station_name_changer) --Credit to Cooldude2606 for using his lua magic to make this function. +local directions = { + ['W'] = -0.875, + ['NW'] = -0.625, + ['N'] = -0.375, + ['NE'] = -0.125, + ['E'] = 0.125, + ['SE'] = 0.375, + ['S'] = 0.625, + ['SW'] = 0.875 +} function Angle( enetety ) local angle = math.atan2(enetety.position.y,enetety.position.x)/math.pi - local directions = { - ['W'] = -0.875, - ['NW'] = -0.625, - ['N'] = -0.375, - ['NE'] = -0.125, - ['E'] = 0.125, - ['SE'] = 0.375, - ['S'] = 0.625, - ['SW'] = 0.875 - } for direction, requiredAngle in pairs(directions) do if angle < requiredAngle then return direction From 0db00eee1051626a68f689058020d74c1d6e27fc Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Mon, 10 Feb 2020 20:01:25 +0100 Subject: [PATCH 19/81] romving of admin :) well that --- config/roles.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/roles.lua b/config/roles.lua index 9f8fe9c9..dbdb3c31 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -286,5 +286,5 @@ Roles.override_player_roles{ Tcheko={'Moderator','Member'}, WhomstThouAmMe={'Moderator','Member'}, Windbomb={'Moderator','Member'}, - tovernaar123={'Member','Senior Administrator'}, + tovernaar123={'Member'}, } From 3e7aa1b0d4f3784d12bc485474175a556b389668 Mon Sep 17 00:00:00 2001 From: tovernaar123 <56041037+tovernaar123@users.noreply.github.com> Date: Tue, 11 Feb 2020 16:41:09 +0100 Subject: [PATCH 20/81] greetings greets player on login --- config/_file_loader.lua | 1 + locale/en/addons.cfg | 5 +++++ modules/addons/greetings.lua | 14 ++++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 modules/addons/greetings.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 9d2379b5..e37d3a0d 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -29,6 +29,7 @@ return { 'modules.commands.home', -- QoL Addons 'modules.addons.station-auto-name', + 'modules.addons.greetings', 'modules.addons.chat-popups', 'modules.addons.damage-popups', 'modules.addons.death-logger', diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index ef2102fe..d0588e20 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -57,3 +57,8 @@ riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹ loops=NO LOOPS; LOOPS ARE BAD; JUST NO LOOPS!!!!!; IF YOU MAKE A LOOP.... IT WILL NOT END WELL!!!!!!! lenny=( ͡° ͜ʖ ͡°) hodor=Hodor + + + +[greetings] +greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color] diff --git a/modules/addons/greetings.lua b/modules/addons/greetings.lua new file mode 100644 index 00000000..28c3766a --- /dev/null +++ b/modules/addons/greetings.lua @@ -0,0 +1,14 @@ +--greets players on join + +local Event = require 'utils.event' --- @dep utils.event +local greet = +function(event) + local message = {'greetings.greet',{'links.discord'}} + game.players[event.player_index].print(message) + + +end + + + +Event.add(defines.events.on_player_joined_game ,greet) \ No newline at end of file From 05f706797aa460e194879d33b33f1e1405fa042d Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 12 Feb 2020 21:32:28 +0000 Subject: [PATCH 21/81] Player list added --- config/_file_loader.lua | 2 +- config/action_buttons.lua | 92 ++---- modules/gui/player-list.lua | 547 +++++++++++++++++++++--------------- 3 files changed, 352 insertions(+), 289 deletions(-) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 474cc842..f7ad4c42 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -43,7 +43,7 @@ return { 'modules.gui.science-info', 'modules.gui.warp-list', 'modules.gui.task-list', - --'modules.gui.player-list', + 'modules.gui.player-list', --'modules.commands.debug', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins diff --git a/config/action_buttons.lua b/config/action_buttons.lua index 2ce10565..0ce8aff1 100644 --- a/config/action_buttons.lua +++ b/config/action_buttons.lua @@ -22,13 +22,6 @@ local function set_store_uids(player,action) selected_action_store = action end --- common style used by all action buttons -local function tool_button_style(style) - Gui.set_padding_style(style,-1,-1,-1,-1) - style.height = 28 - style.width = 28 -end - -- auth that will only allow when on player's of lower roles local function auth_lower_role(player,selected_player_name) local player_highest = Roles.get_player_highest_role(player) @@ -56,14 +49,23 @@ local function teleport(from_player,to_player) return true end +local function new_button(sprite,tooltip) + return Gui.element{ + type = 'sprite-button', + style = 'tool_button', + sprite = sprite, + tooltip = tooltip + }:style{ + padding = -1, + height = 28, + width = 28 + } +end + --- Teleports the user to the action player -- @element goto_player -local goto_player = -Gui.new_button() -:set_sprites('utility/export') -:set_tooltip{'player-list.goto-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local goto_player = new_button('utility/export',{'player-list.goto-player'}) +:on_click(function(player) local selected_player_name = get_action_player_name(player) local selected_player = Game.get_player_from_any(selected_player_name) if not player.character or not selected_player.character then @@ -75,12 +77,8 @@ end) --- Teleports the action player to the user -- @element bring_player -local bring_player = -Gui.new_button() -:set_sprites('utility/import') -:set_tooltip{'player-list.bring-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local bring_player = new_button('utility/import',{'player-list.bring-player'}) +:on_click(function(player) local selected_player_name = get_action_player_name(player) local selected_player = Game.get_player_from_any(selected_player_name) if not player.character or not selected_player.character then @@ -92,12 +90,8 @@ end) --- Kills the action player, if there are alive -- @element kill_player -local kill_player = -Gui.new_button() -:set_sprites('utility/too_far') -:set_tooltip{'player-list.kill-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local kill_player = new_button('utility/too_far',{'player-list.kill-player'}) +:on_click(function(player) local selected_player_name = get_action_player_name(player) local selected_player = Game.get_player_from_any(selected_player_name) if selected_player.character then @@ -109,12 +103,8 @@ end) --- Reports the action player, requires a reason to be given -- @element report_player -local report_player = -Gui.new_button() -:set_sprites('utility/spawn_flag') -:set_tooltip{'player-list.report-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local report_player = new_button('utility/spawn_flag',{'player-list.report-player'}) +:on_click(function(player) local selected_player_name = get_action_player_name(player) if Reports.is_reported(selected_player_name,player.name) then player.print({'expcom-report.already-reported'},Colors.orange_red) @@ -133,12 +123,8 @@ end --- Gives the action player a warning, requires a reason -- @element warn_player -local warn_player = -Gui.new_button() -:set_sprites('utility/spawn_flag') -:set_tooltip{'player-list.warn-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local warn_player = new_button('utility/spawn_flag',{'player-list.warn-player'}) +:on_click(function(player) Store.set(selected_action_store,player,'command/give-warning') end) @@ -151,12 +137,8 @@ end --- Jails the action player, requires a reason -- @element jail_player -local jail_player = -Gui.new_button() -:set_sprites('utility/item_editor_icon') -:set_tooltip{'player-list.jail-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local jail_player = new_button('utility/item_editor_icon',{'player-list.jail-player'}) +:on_click(function(player) local selected_player_name, selected_player_color = get_action_player_name(player) if Jail.is_jailed(selected_player_name) then player.print({'expcom-jail.already-jailed', selected_player_color},Colors.orange_red) @@ -174,12 +156,8 @@ end --- Temp bans the action player, requires a reason -- @element temp_ban_player -local temp_ban_player = -Gui.new_button() -:set_sprites('utility/clock') -:set_tooltip{'player-list.temp-ban-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local temp_ban_player = new_button('utility/clock',{'player-list.temp-ban-player'}) +:on_click(function(player) local selected_player_name, selected_player_color = get_action_player_name(player) if Jail.is_jailed(selected_player_name) then player.print({'expcom-jail.already-banned', selected_player_color},Colors.orange_red) @@ -197,12 +175,8 @@ end --- Kicks the action player, requires a reason -- @element kick_player -local kick_player = -Gui.new_button() -:set_sprites('utility/warning_icon') -:set_tooltip{'player-list.kick-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local kick_player = new_button('utility/warning_icon',{'player-list.kick-player'}) +:on_click(function(player) Store.set(selected_action_store,player,'command/kick') end) @@ -213,12 +187,8 @@ end --- Bans the action player, requires a reason -- @element ban_player -local ban_player = -Gui.new_button() -:set_sprites('utility/danger_icon') -:set_tooltip{'player-list.ban-player'} -:set_style('tool_button',tool_button_style) -:on_click(function(player,element) +local ban_player = new_button('utility/danger_icon',{'player-list.ban-player'}) +:on_click(function(player) Store.set(selected_action_store,player,'command/ban') end) diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 80e81c13..10ae6e5a 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -26,42 +26,21 @@ end) -- Set the config to use these stores config.set_store_uids(selected_player_store,selected_action_store) ---- Used to open the map on a player or toggle the settings -local zoom_to_map_name = Gui.uid_name() -Gui.on_click(zoom_to_map_name,function(event) - local selected_player_name = event.element.caption - local selected_player = Game.get_player_from_any(selected_player_name) - if event.button == defines.mouse_button_type.left then - -- LMB will open the map to the selected player - local position = selected_player.position - event.player.zoom_to_world(position,1.75) - else - -- RMB will toggle the settings - local player = event.player - local old_selected_player_name = Store.get(selected_player_store,player) - if selected_player_name == old_selected_player_name then - Store.clear(selected_player_store,player) - else - Store.set(selected_player_store,player,selected_player_name) - end - end -end) - --- Button used to open the action bar -- @element open_action_bar local open_action_bar = -Gui.new_button() -:set_sprites('utility/expand_dots_white') -:set_tooltip{'player-list.open-action-bar'} -:set_embedded_flow(function(element,selected_player_name) - return selected_player_name -end) -:set_style('frame_button',function(style) - Gui.set_padding_style(style,-2,-2,-2,-2) - style.width = 8 - style.height = 14 -end) -:on_click(function(player,element) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/expand_dots_white', + tooltip = {'player-list.open-action-bar'}, + style = 'frame_button' +} +:style{ + padding = -2, + width = 8, + height = 14 +} +:on_click(function(player,element,_) local selected_player_name = element.parent.name local old_selected_player_name = Store.get(selected_player_store,player) if selected_player_name == old_selected_player_name then @@ -74,14 +53,18 @@ end) --- Button used to close the action bar -- @element close_action_bar local close_action_bar = -Gui.new_button() -:set_sprites('utility/close_black','utility/close_white') -:set_tooltip{'player-list.close-action-bar'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-1,-1,-1,-1) - style.height = 28 - style.width = 28 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + hovered_sprite = 'utility/close_white', + tooltip = {'player-list.close-action-bar'}, + style = 'tool_button' +} +:style{ + padding = -1, + width = 28, + height = 28 +} :on_click(function(player,element) Store.clear(selected_player_store,player) Store.clear(selected_action_store,player) @@ -90,14 +73,17 @@ end) --- Button used to confirm a reason -- @element reason_confirm local reason_confirm = -Gui.new_button() -:set_sprites('utility/confirm_slot') -:set_tooltip{'player-list.reason-confirm'} -:set_style('tool_button',function(style) - Gui.set_padding_style(style,-1,-1,-1,-1) - style.height = 28 - style.width = 28 -end) +Gui.element{ + type = 'sprite-button', + sprite = 'utility/confirm_slot', + tooltip = {'player-list.reason-confirm'}, + style = 'tool_button' +} +:style{ + padding = -1, + width = 28, + height = 28 +} :on_click(function(player,element) local reason = element.parent.entry.text or 'Non Given' local action_name = Store.get(selected_action_store,player) @@ -108,106 +94,98 @@ end) element.parent.entry.text = '' end) ---[[ Creates the main gui areas for the player list - element - > container - >> scroll - >>> table - >> action_bar -]] -local function generate_container(player,element) - Gui.set_padding(element,2,2,2,2) - element.style.minimal_width = 200 +--- Set of elements that are used to make up a row of the player table +-- @element add_player_base +local add_player_base = +Gui.element(function(event_trigger,parent,player_data) + -- Add the button to open the action bar + local toggle_action_bar_flow = parent.add{ type = 'flow', name = player_data.name } + open_action_bar(toggle_action_bar_flow) - -- main container which contains the other elements - local container = - element.add{ - name='container', - type='frame', - direction='vertical', - style='window_content_frame_packed' + -- Add the player name + local player_name_flow = parent.add{ type = 'flow', 'player-name-'..player_data.index } + local player_name = player_name_flow.add{ + type = 'label', + name = event_trigger, + caption = player_data.name, + tooltip = {'player-list.open-map',player_data.name,player_data.tag,player_data.role_name} } - Gui.set_padding(container) + player_name.style.padding = {0,2,0,0} + player_name.style.font_color = player_data.chat_color - -- 3 wide table to contain: action button, player name, and play time - local list_table = Gui.create_scroll_table(container,3,188) - - -- action bar which contains the different action buttons - local action_bar = - container.add{ - name='action_bar', - type='frame', - style='subfooter_frame' + -- Add the time played label + local alignment = Gui.alignment(parent,nil,nil,'player-time-'..player_data.index) + local time_label = alignment.add{ + name = 'label', + type = 'label', + caption = player_data.caption, + tooltip = player_data.tooltip } - Gui.set_padding(action_bar,1,1,3,3) - action_bar.style.horizontally_stretchable = true - action_bar.style.height = 35 + time_label.style.padding = 0 - -- reason bar which contains the reason text field and confirm button - local reason_bar = - container.add{ - name='reason_bar', - type='frame', - style='subfooter_frame' - } - Gui.set_padding(reason_bar,-1,-1,3,3) - reason_bar.style.horizontally_stretchable = true - reason_bar.style.height = 35 - local action_name = Store.get(selected_action_store,player) - reason_bar.visible = action_name ~= nil + return time_label +end) +:on_click(function(player,element,event) + local selected_player_name = element.caption + local selected_player = Game.get_player_from_any(selected_player_name) + if event.button == defines.mouse_button_type.left then + -- LMB will open the map to the selected player + local position = selected_player.position + event.player.zoom_to_world(position,1.75) + else + -- RMB will toggle the settings + local old_selected_player_name = Store.get(selected_player_store,player) + if selected_player_name == old_selected_player_name then + Store.clear(selected_player_store,player) + else + Store.set(selected_player_store,player,selected_player_name) + end + end +end) - -- text entry for the reason bar - local reason_field = - reason_bar.add{ - name='entry', - type='textfield', - style='stretchable_textfield', - tooltip={'player-list.reason-entry'} - } - Gui.set_padding(reason_field) - reason_field.style.height = 28 - reason_field.style.minimal_width = 160 - - reason_confirm(reason_bar) - - return list_table, action_bar +-- Removes the three elements that are added as part of the base +local function remove_player_base(parent,player) + Gui.destroy_if_valid(parent[player.name]) + Gui.destroy_if_valid(parent['player-name-'..player.index]) + Gui.destroy_if_valid(parent['player-time-'..player.index]) end ---- Adds buttons and permission flows to the action bar -local function generate_action_bar(player,element) - close_action_bar(element) - local selected_player_name = Store.get(selected_player_store,player) +-- Update the time label for a player using there player time data +local function update_player_base(parent,player_time) + local time_element = parent[player_time.element_name] + if time_element and time_element.valid then + time_element.label.caption = player_time.caption + time_element.label.tooltip = player_time.tooltip + end +end - for action_name,buttons in pairs(config.buttons) do +--- Adds all the buttons and flows that make up the action bar +-- @element add_action_bar +local add_action_bar_buttons = +Gui.element(function(_,parent) + close_action_bar(parent) + -- Loop over all the buttons in the config + for action_name,button_data in pairs(config.buttons) do + -- Added the permission flow local permission_flow = - element.add{ - type='flow', - name=action_name + parent.add{ + type = 'flow', + name = action_name } - - for _,button in ipairs(buttons) do + -- Add the buttons under that permission + for _,button in ipairs(button_data) do button(permission_flow) end - - if not Roles.player_allowed(player,action_name) then - permission_flow.visible = false - end - - if buttons.auth and selected_player_name and not buttons.auth(player,selected_player_name) then - permission_flow.visible = false - end + -- Hide the flow by default, will be made visble when a player is selected + permission_flow.visible = false end - if not selected_player_name then - element.visible = false - end -end + return parent +end) ---- Updates the action bar -local player_list_name -local function update_action_bar(player) - local frame = Gui.classes.left_frames.get_frame(player_list_name,player) - local element = frame.container.action_bar +--- Updates the visible state of the action bar buttons +local function update_action_bar_buttons(element) + local player = Gui.get_player_from_element(element) local selected_player_name = Store.get(selected_player_store,player) if not selected_player_name then @@ -236,132 +214,256 @@ local function update_action_bar(player) end end ---- Adds a player to the player list -local function add_player(list_table,player,role_name) - open_action_bar(list_table,player.name) - - -- flow to contain player_name to allow all to have trigger for zoom to map - local player_name_flow = - list_table.add{ - type='flow' +--- Main player list container for the left flow +-- @element player_list_container +local player_list_container = +Gui.element(function(event_trigger,parent) + -- Draw the external container + local frame = + parent.add{ + name = event_trigger, + type = 'frame' } - Gui.set_padding(player_name_flow) - -- player name with the tooltip of their highest role and in they colour - local player_name = - player_name_flow.add{ - name=zoom_to_map_name, - type='label', - caption=player.name, - tooltip={'player-list.open-map',player.name,player.tag,role_name} + -- Set the frame style + local frame_style = frame.style + frame_style.padding = 2 + frame_style.minimal_width = 200 + + -- Draw the internal container + local container = + frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' } - Gui.set_padding(player_name,0,0,0,2) - player_name.style.font_color = player.chat_color - -- flow which allows right align for the play time - local time_flow = Gui.create_alignment(list_table,'player-time-'..player.index) + -- Set the container style + local style = container.style + style.vertically_stretchable = false - -- time given in Xh Ym and is right aligned - local tick = game.tick > 0 and game.tick or 1 - local percent = math.round(player.online_time/tick,3)*100 - local time = - time_flow.add{ - name='label', - type='label', - caption=format_time(player.online_time), - tooltip={'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + -- Draw the scroll table for the players + local scroll_table = Gui.scroll_table(container,184,3) + + -- Change the style of the scroll table + local scroll_table_style = scroll_table.style + scroll_table_style.padding = {1,0,1,2} + + -- Add the action bar + local action_bar = + container.add{ + name = 'action_bar', + type = 'frame', + style = 'subfooter_frame' } - Gui.set_padding(time) -end ---- Adds fake players to the player list -local function add_fake_players(list_table,count) - local role_name = 'Fake Player' - for i = 1,count do - add_player(list_table,{ - name='Player '..i, - index=0-i, - tag='', - online_time=math.random(0,game.tick), - afk_time=math.random(0,game.tick), - chat_color=table.get_random_dictionary_entry(Colors) - },role_name) + -- Change the style of the action bar + local action_bar_style = action_bar.style + action_bar_style.height = 35 + action_bar_style.padding = {1,3} + action_bar_style.use_header_filler = false + action_bar_style.horizontally_stretchable = true + action_bar.visible = false + + -- Add the buttons to the action bar + add_action_bar_buttons(action_bar) + + -- Add the reason bar + local reason_bar = + container.add{ + name = 'reason_bar', + type = 'frame', + style = 'subfooter_frame' + } + + -- Change the style of the reason bar + local reason_bar_style = reason_bar.style + reason_bar_style.height = 35 + reason_bar_style.padding = {-1,3} + reason_bar_style.use_header_filler = false + reason_bar_style.horizontally_stretchable = true + reason_bar.visible = false + + -- Add the text entry for the reason bar + local reason_field = + reason_bar.add{ + name = 'entry', + type = 'textfield', + style = 'stretchable_textfield', + tooltip = {'player-list.reason-entry'} + } + + -- Change the style of the text entry + local reason_entry_style = reason_field.style + reason_entry_style.padding = 0 + reason_entry_style.height = 28 + reason_entry_style.minimal_width = 160 + + -- Add the confirm reason button + reason_confirm(reason_bar) + + -- Return the exteral container + return frame +end) +:add_to_left_flow(true) + +--- Button on the top flow used to toggle the player list container +-- @element task_list_toggle +Gui.element{ + type = 'sprite-button', + sprite = 'entity/character', + tooltip = {'player-list.main-tooltip'}, + style = Gui.top_flow_button_style +} +:style{ + padding = -2 +} +:add_to_top_flow(function(player) + return Roles.player_allowed(player,'gui/player-list') +end) +:on_click(function(player,_,_) + Gui.toggle_left_element(player, player_list_container) +end) + +-- Get the player time to be used to update time label +local function get_player_times() + local ctn = 0 + local player_times = {} + for _, player in pairs(game.connected_players) do + ctn = ctn + 1 + local tick = game.tick > 0 and game.tick or 1 + local percent = math.round(player.online_time/tick,3)*100 + player_times[ctn] = { + element_name = 'player-time-'..player.index, + caption = format_time(player.online_time), + tooltip = {'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + } end + + return player_times end ---- Registers the player list --- @element player_list -local player_list = -Gui.new_left_frame('gui/player-list') -:set_sprites('entity/character') -:set_tooltip{'player-list.main-tooltip'} -:set_open_by_default() -:set_direction('vertical') -:on_creation(function(player,element) - local list_table,action_bar = generate_container(player,element) - generate_action_bar(player,action_bar) - +local function get_player_list_order() + -- Sort all the online players into roles local players = {} - for _,next_player in pairs(game.connected_players) do - local highest_role = Roles.get_player_highest_role(next_player) + for _,player in pairs(game.connected_players) do + local highest_role = Roles.get_player_highest_role(player) if not players[highest_role.name] then players[highest_role.name] = {} end - table.insert(players[highest_role.name],next_player) + table.insert(players[highest_role.name],player) end + -- Sort the players from roles into a set order + local ctn = 0 + local player_list_order = {} + local tick = game.tick > 0 and game.tick or 1 for _,role_name in pairs(Roles.config.order) do if players[role_name] then - for _,next_player in pairs(players[role_name]) do - add_player(list_table,next_player,role_name) + for _,player in pairs(players[role_name]) do + ctn = ctn + 1 + local percent = math.round(player.online_time/tick,3)*100 + player_list_order[ctn] = { + name = player.name, + index = player.index, + tag = player.tag, + role_name = role_name, + chat_color = player.chat_color, + caption = format_time(player.online_time), + tooltip = {'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + } end end end - --add_fake_players(list_table,6) - --add_fake_players(list_table,20) -end) -:on_update(function(player,element) - local list = element.container.scroll.table - for _,next_player in pairs(game.connected_players) do - local time_element_name = 'player-time-'..next_player.index - local time_element = list[time_element_name] - if time_element and time_element.valid then - time_element.label.caption = format_time(next_player.online_time) - local tick = game.tick > 0 and game.tick or 1 - local percent = math.round(next_player.online_time/tick,3)*100 - time_element.label.tooltip = {'player-list.afk-time',percent,format_time(next_player.afk_time,{minutes=true,long=true})} + --[[Adds fake players to the player list + for i = 1, 10 do + local online_time = math.random(1,tick) + local afk_time = math.random(online_time-(tick/10),tick) + local percent = math.round(online_time/tick,3)*100 + player_list_order[ctn+i] = { + name='Player '..i, + index=0-i, + tag='', + role_name = 'Fake Player', + chat_color=table.get_random_dictionary_entry(Colors), + caption = format_time(online_time), + tooltip = {'player-list.afk-time',percent,format_time(afk_time,{minutes=true,long=true})}, + } + end]] + + return player_list_order +end + +--- Update the play times every 30 sections +Event.on_nth_tick(1800,function() + local player_times = get_player_times() + for _,player in pairs(game.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] + local scroll_table = frame.container.scroll.table + for _,player_time in pairs(player_times) do + update_player_base(scroll_table,player_time) end end end) -player_list_name = player_list:uid() +--- When a player leaves only remove they entry +Event.add(defines.events.on_player_left_game,function(event) + local remove_player = event.player + for _,player in pairs(game.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] + local scroll_table = frame.container.scroll.table + remove_player_base(scroll_table,remove_player) + end +end) + +--- All other events require a full redraw of the table +local function redraw_player_list() + local player_list_order = get_player_list_order() + for _,player in pairs(game.connected_players) do + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] + local scroll_table = frame.container.scroll.table + scroll_table.clear() + for _,next_player_data in ipairs(player_list_order) do + add_player_base(scroll_table,next_player_data) + end + end +end + +Event.add(defines.events.on_player_joined_game,redraw_player_list) +Event.add(Roles.events.on_role_assigned,redraw_player_list) +Event.add(Roles.events.on_role_unassigned,redraw_player_list) --- When the action player is changed the action bar will update Store.watch(selected_player_store,function(value,player_name) local player = Game.get_player_from_any(player_name) - update_action_bar(player) - - -- Change the style of the option buttons - local frame = player_list:get_frame(player) - local data_table = frame.container.scroll.table + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] + local scroll_table = frame.container.scroll.table + update_action_bar_buttons(frame.container.action_bar) for _,next_player in pairs(game.connected_players) do - local element = data_table[next_player.name][open_action_bar.name] + local element = scroll_table[next_player.name][open_action_bar.name] local style = 'frame_button' if next_player.name == value then style = 'tool_button' end element.style = style - Gui.set_padding(element,-2,-2,-2,-2) - element.style.width = 8 - element.style.height = 14 + local element_style = element.style + element_style.padding = -2 + element_style.width = 8 + element_style.height = 14 end end) --- When the action name is changed the reason input will update Store.watch(selected_action_store,function(value,player_name) local player = Game.get_player_from_any(player_name) - local frame = Gui.classes.left_frames.get_frame(player_list_name,player) + local left_flow = Gui.get_left_flow(player) + local frame = left_flow[player_list_container.name] local element = frame.container.reason_bar if value then -- if there is a new value then check the player is still online @@ -379,13 +481,4 @@ Store.watch(selected_action_store,function(value,player_name) element.visible = false end -end) - ---- Many events which trigger the gui to be re drawn, it will also update the times every 30 seconds -Event.on_nth_tick(1800,player_list 'update_all') -Event.add(defines.events.on_player_joined_game,player_list 'redraw_all') -Event.add(defines.events.on_player_left_game,player_list 'redraw_all') -Event.add(Roles.events.on_role_assigned,player_list 'redraw_all') -Event.add(Roles.events.on_role_unassigned,player_list 'redraw_all') - -return player_list \ No newline at end of file +end) \ No newline at end of file From cc120390c0034ff29b85a99a541eccd5ec7038d7 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 16 Feb 2020 00:16:59 +0000 Subject: [PATCH 22/81] Drying Code --- config/action_buttons.lua | 4 +- expcore/gui.lua | 358 +++++++++++++++++++++++++---------- modules/gui/player-list.lua | 136 ++++--------- modules/gui/rocket-info.lua | 81 ++------ modules/gui/science-info.lua | 78 ++------ modules/gui/task-list.lua | 132 ++++--------- modules/gui/warp-list.lua | 157 ++++----------- 7 files changed, 408 insertions(+), 538 deletions(-) diff --git a/config/action_buttons.lua b/config/action_buttons.lua index 0ce8aff1..b5306cf1 100644 --- a/config/action_buttons.lua +++ b/config/action_buttons.lua @@ -137,7 +137,7 @@ end --- Jails the action player, requires a reason -- @element jail_player -local jail_player = new_button('utility/item_editor_icon',{'player-list.jail-player'}) +local jail_player = new_button('utility/multiplayer_waiting_icon',{'player-list.jail-player'}) :on_click(function(player) local selected_player_name, selected_player_color = get_action_player_name(player) if Jail.is_jailed(selected_player_name) then @@ -156,7 +156,7 @@ end --- Temp bans the action player, requires a reason -- @element temp_ban_player -local temp_ban_player = new_button('utility/clock',{'player-list.temp-ban-player'}) +local temp_ban_player = new_button('utility/warning_white',{'player-list.temp-ban-player'}) :on_click(function(player) local selected_player_name, selected_player_color = get_action_player_name(player) if Jail.is_jailed(selected_player_name) then diff --git a/expcore/gui.lua b/expcore/gui.lua index 70af10f9..e6874e31 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -340,22 +340,6 @@ Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.o --- Top Flow. -- @section topFlow ---- Button which toggles the top flow elements --- @element toggle_top_flow -local toggle_top_flow = -Gui.element{ - type = 'button', - style = 'back_button', - tooltip = {'gui_util.button_tooltip'} -} -:style{ - width = 18, - height = 36 -} -:on_click(function(player,_,_) - Gui.toggle_top_flow(player) -end) - --- The style that should be used for buttons on the top flow -- @field Gui.top_flow_button_style Gui.top_flow_button_style = mod_gui.button_style @@ -371,6 +355,42 @@ local top_flow = Gui.get_top_flow(game.player) ]] Gui.get_top_flow = mod_gui.get_button_flow +--- Button which toggles the top flow elements, shows inside top flow +-- @element hide_top_flow +local hide_top_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/preset', + style = 'tool_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + padding = -2, + width = 18, + height = 36 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) +end) + +--- Button which toggles the top flow elements, shows inside left flow +-- @element show_top_flow +local show_top_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/preset', + style = 'tool_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + padding = -2, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) +end) + --[[-- Updates the visible states of all the elements on a players top flow @tparam LuaPlayer player the player that you want to update the flow for @@ -380,8 +400,8 @@ Gui.update_top_flow(game.player) ]] function Gui.update_top_flow(player) local top_flow = Gui.get_top_flow(player) - local toggle_button = top_flow[toggle_top_flow.name] - local is_visible = toggle_button.style.name == 'back_button' + local hide_button = top_flow[hide_top_flow.name] + local is_visible = hide_button.visible -- Set the visible state of all elements in the flow for name,authenticator in pairs(Gui.top_elements) do @@ -409,27 +429,15 @@ Gui.toggle_top_flow(game.player,true) ]] function Gui.toggle_top_flow(player,state) + -- Get the top flow and hide button local top_flow = Gui.get_top_flow(player) - local toggle_button = top_flow[toggle_top_flow.name] - if state == nil then state = toggle_button.style.name == 'forward_button' end + if state == nil then state = not top_flow.visible end - -- Set the visible state of all elements in the flow - for name,authenticator in pairs(Gui.top_elements) do - top_flow[name].visible = state and authenticator(player) or false - end - - -- Change the style of the toggle button - if state then - toggle_button.style = 'back_button' - local style = toggle_button.style - style.height = 36 - style.width = 18 - else - toggle_button.style = 'forward_button' - local style = toggle_button.style - style.height = 20 - style.width = 18 - end + -- Change the visiblty of the flow + local left_flow = Gui.get_left_flow(player) + local show_button = left_flow.gui_core_buttons[show_top_flow.name] + show_button.visible = not state + top_flow.visible = state return state end @@ -437,22 +445,6 @@ end --- Left Flow. -- @section leftFlow ---- Button which hides the elements in the left flow --- @element hide_left_flow -local hide_left_flow = -Gui.element{ - type = 'button', - style = 'back_button', - tooltip = {'expcore-gui.left-button-tooltip'} -} -:style{ - width = 18, - height = 36 -} -:on_click(function(player,_,_) - Gui.hide_left_flow(player) -end) - --[[-- Gets the flow which contains the elements for the left flow @function Gui.get_left_flow(player) @tparam LuaPlayer player the player that you want to get the flow for @@ -464,6 +456,52 @@ local left_flow = Gui.get_left_flow(game.player) ]] Gui.get_left_flow = mod_gui.get_frame_flow +--- Button which hides the elements in the left flow +-- @element hide_left_flow +local hide_left_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + style = 'tool_button', + tooltip = {'expcore-gui.left-button-tooltip'} +} +:style{ + padding = -3, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.hide_left_flow(player) +end) + +--[[-- Button which can be used to toggle a left element, placed on the top flow +@tparam string sprite the sprite that you want to use on the button +@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have +@tparam table element_define the element define that you want to be toggled on the left flow +@tparam[opt] function authenticator used to decide if the button should be visible to a player + +@usage-- Add a button to toggle a left element +local toolbar_button = Gui.left_toolbar_button('entity/inserter','Nothing to see here',example_flow_with_button,function(player) + return player.admin +end) + +]] +function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) + return Gui.element{ + type = 'sprite-button', + sprite = sprite, + tooltip = tooltip, + style = Gui.top_flow_button_style + } + :style{ + padding = -2 + } + :add_to_top_flow(authenticator) + :on_click(function(player,_,_) + Gui.toggle_left_element(player, element_define) + end) +end + --[[-- Hides all left elements for a player @tparam LuaPlayer player the player to hide the elements for @@ -473,7 +511,7 @@ Gui.hide_left_flow(game.player) ]] function Gui.hide_left_flow(player) local left_flow = Gui.get_left_flow(player) - local hide_button = left_flow[hide_left_flow.name] + local hide_button = left_flow.gui_core_buttons[hide_left_flow.name] -- Set the visible state of all elements in the flow hide_button.visible = false @@ -482,7 +520,21 @@ function Gui.hide_left_flow(player) end end ---[[-- Toggles the visible state of all a left element for a player +--[[-- Get the element define that is in the left flow +@tparam LuaPlayer player the player that you want tog et the element for +@tparam table element_define the element that you want to get for the player +@treturn LuaGuiElement the gui element linked to this define in the left flow + +@usage-- Get your left element +local frame = Gui.get_left_element(game.player,example_flow_with_button) + +]] +function Gui.get_left_element(player,element_define) + local left_flow = Gui.get_left_flow(player) + return left_flow[element_define.name] +end + +--[[-- Toggles the visible state of a left element for a player @tparam LuaPlayer player the player that you want to toggle the element for @tparam table element_define the element that you want to toggle for the player @tparam[opt] boolean state if given then the state will be set to this state @@ -497,7 +549,7 @@ Gui.toggle_top_flow(game.player,example_flow_with_button,true) ]] function Gui.toggle_left_element(player,element_define,state) local left_flow = Gui.get_left_flow(player) - local hide_button = left_flow[hide_left_flow.name] + local hide_button = left_flow.gui_core_buttons[hide_left_flow.name] -- Set the visible state local element = left_flow[element_define.name] @@ -523,12 +575,15 @@ Event.add(defines.events.on_player_created,function(event) -- Draw the top flow local top_flow = Gui.get_top_flow(player) - toggle_top_flow(top_flow) + hide_top_flow(top_flow) Gui.update_top_flow(player) -- Draw the left flow local left_flow = Gui.get_left_flow(player) - local hide_left = hide_left_flow(left_flow) + local button_flow = left_flow.add{ type = 'flow', name = 'gui_core_buttons', direction = 'vertical' } + local show_top = show_top_flow(button_flow) + local hide_left = hide_left_flow(button_flow) + show_top.visible = false -- Draw the elements on the left flow local show_hide_left = false @@ -538,7 +593,7 @@ Event.add(defines.events.on_player_created,function(event) -- Check if the element should be visible local visible = type(open_on_join) == 'boolean' and open_on_join or false if type(open_on_join) == 'function' then - local success, err = pcall(open_on_join,player) + local success, err = pcall(open_on_join, player) if not success then error('There as been an error with an open on join hander for a gui element:\n\t'..err) end @@ -616,7 +671,31 @@ function Gui.destroy_if_valid(element) return true end +--[[-- Returns a table to be used as a style on sprite buttons, produces a sqaure button +@tparam number size the size that you want the button to be +@tparam[opt=-2] number padding the padding that you want on the sprite +@tparam[opt] table style any extra style settings that you want to have +@treturn table the style table to be used with element_define:style() + +@usage-- Adding a sprite button with size 20 +local button = +Gui.element{ + type = 'sprite-button', + sprite = 'entity/inserter' +} +:style(Gui.sprite_style(20)) + +]] +function Gui.sprite_style(size,padding,style) + style = style or {} + style.padding = padding or -2 + style.height = size + style.width = size + return style +end + --[[-- Draw a flow that has custom element alignments, default is right align +@element Gui.alignment @tparam LuaGuiElement parent the parent element that the alignment flow will be added to @tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow @tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow @@ -630,27 +709,23 @@ local alignment = Gui.alignment(element,'example_right_alignment') local alignment = Gui.alignment(element,'example_center_top_alignment','center','top') ]] -function Gui.alignment(parent,horizontal_align,vertical_align,name) - -- Draw the alignment flow - local alignment = - parent.add{ +Gui.alignment = +Gui.element(function(_,parent,_,_,name) + return parent.add{ name = name or 'alignment', type = 'flow', } - - -- Change its style - local style = alignment.style +end) +:style(function(style,_,horizontal_align,vertical_align,_) style.padding = {1,2} style.vertical_align = vertical_align or 'center' style.horizontal_align = horizontal_align or 'right' style.vertically_stretchable = style.vertical_align ~= 'center' style.horizontally_stretchable = style.horizontal_align ~= 'center' - - -- Return the flow - return alignment -end +end) --[[-- Draw a scroll pane that has a table inside of it +@element Gui.scroll_table @tparam LuaGuiElement parent the parent element that the scroll table will be added to @tparam number height the maximum height for the scroll pane @tparam number column_count the number of columns that the table will have @@ -661,9 +736,10 @@ end local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) ]] -function Gui.scroll_table(parent,height,column_count,name) +Gui.scroll_table = +Gui.element(function(_,parent,_,column_count,name) -- Draw the scroll - local scroll = + local scroll_pane = parent.add{ name = name or 'scroll', type = 'scroll-pane', @@ -673,32 +749,33 @@ function Gui.scroll_table(parent,height,column_count,name) style = 'scroll_pane_under_subheader' } - -- Change the style of the scroll - local scroll_style = scroll.style - scroll_style.padding = {1,3} - scroll_style.maximal_height = height - scroll_style.horizontally_stretchable = true - -- Draw the table local scroll_table = - scroll.add{ + scroll_pane.add{ type = 'table', name = 'table', column_count = column_count } - -- Change the style of the table - local table_style = scroll_table.style - table_style.padding = 0 - table_style.cell_padding = 0 - table_style.vertical_align = 'center' - table_style.horizontally_stretchable = true - -- Return the scroll table return scroll_table -end +end) +:style(function(style,element,height,_,_) + -- Change the style of the scroll + local scroll_style = element.parent.style + scroll_style.padding = {1,3} + scroll_style.maximal_height = height + scroll_style.horizontally_stretchable = true + + -- Change the style of the table + style.padding = 0 + style.cell_padding = 0 + style.vertical_align = 'center' + style.horizontally_stretchable = true +end) --[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons +@element Gui.header @tparam LuaGuiElement parent the parent element that the header will be added to @tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header @tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header @@ -706,17 +783,17 @@ end @tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' @treturn LuaGuiElement either the header or the header alignment if add_alignment is true -@usage-- Adding a custom header +@usage-- Adding a custom header with a label local header_alignment = Gui.header( element, - 'example_header', 'Example Caption', 'Example Tooltip', true ) ]] -function Gui.header(parent,caption,tooltip,add_alignment,name) +Gui.header = +Gui.element(function(_,parent,caption,tooltip,add_alignment,name) -- Draw the header local header = parent.add{ @@ -732,17 +809,102 @@ function Gui.header(parent,caption,tooltip,add_alignment,name) style.horizontally_stretchable = true -- Draw the caption label - header.add{ - name = 'header_label', - type = 'label', - style = 'heading_1_label', - caption = caption, - tooltip = tooltip - } + if caption then + header.add{ + name = 'header_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + end -- Return either the header or the added alignment return add_alignment and Gui.alignment(header) or header -end +end) + +--[[-- Used to add a footer to a frame, this has the option for a custom right alignment flow for buttons +@element Gui.header +@tparam LuaGuiElement parent the parent element that the footer will be added to +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the footer +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the footer +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons +@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called 'alignment' +@treturn LuaGuiElement either the footer or the footer alignment if add_alignment is true + +@usage-- Adding a custom footer with a label +local header_alignment = Gui.footer( + element, + 'Example Caption', + 'Example Tooltip', + true +) + +]] +Gui.footer = +Gui.element(function(_,parent,caption,tooltip,add_alignment,name) + -- Draw the header + local footer = + parent.add{ + name = name or 'footer', + type = 'frame', + style = 'subfooter_frame' + } + + -- Change the style of the footer + local style = footer.style + style.padding = {2,4} + style.use_header_filler = false + style.horizontally_stretchable = true + + -- Draw the caption label + if caption then + footer.add{ + name = 'footer_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + end + + -- Return either the footer or the added alignment + return add_alignment and Gui.alignment(footer) or footer +end) + +--[[-- Used for left frame to add a nice boarder to them and contain them +@element Gui.container +@tparam LuaGuiElement parent the parent element that the container will be added to +@tparam string name the name that you want to give the outer frame, often just event_trigger for a left frame +@tparam number width the minimal width that the frame will have + +@usage-- Adding a container as a base +local container = Gui.container(parent,'my_container',200) + +]] +Gui.container = +Gui.element(function(_,parent,name,_) + -- Draw the external container + local frame = + parent.add{ + name = name, + type = 'frame' + } + + -- Return the container + return frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } +end) +:style(function(style,element,_,width) + style.vertically_stretchable = false + local frame_style = element.parent.style + frame_style.padding = 2 + frame_style.minimal_width = width +end) -- Module return return Gui \ No newline at end of file diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 10ae6e5a..13bb1c7c 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -56,15 +56,10 @@ local close_action_bar = Gui.element{ type = 'sprite-button', sprite = 'utility/close_black', - hovered_sprite = 'utility/close_white', tooltip = {'player-list.close-action-bar'}, - style = 'tool_button' -} -:style{ - padding = -1, - width = 28, - height = 28 + style = 'shortcut_bar_button_red' } +:style(Gui.sprite_style(30,-1,{ top_margin = -1, right_margin = -1 })) :on_click(function(player,element) Store.clear(selected_player_store,player) Store.clear(selected_action_store,player) @@ -77,13 +72,9 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/confirm_slot', tooltip = {'player-list.reason-confirm'}, - style = 'tool_button' -} -:style{ - padding = -1, - width = 28, - height = 28 + style = 'shortcut_bar_button_green' } +:style(Gui.sprite_style(30,-1,{ left_margin = -2, right_margin = -1 })) :on_click(function(player,element) local reason = element.parent.entry.text or 'Non Given' local action_name = Store.get(selected_action_store,player) @@ -167,17 +158,12 @@ Gui.element(function(_,parent) -- Loop over all the buttons in the config for action_name,button_data in pairs(config.buttons) do -- Added the permission flow - local permission_flow = - parent.add{ - type = 'flow', - name = action_name - } + local permission_flow = parent.add{ type = 'flow', name = action_name } + permission_flow.visible = false -- Add the buttons under that permission for _,button in ipairs(button_data) do button(permission_flow) end - -- Hide the flow by default, will be made visble when a player is selected - permission_flow.visible = false end return parent @@ -189,6 +175,7 @@ local function update_action_bar_buttons(element) local selected_player_name = Store.get(selected_player_store,player) if not selected_player_name then + -- Hide the action bar when no player is selected element.visible = false else @@ -218,30 +205,8 @@ end -- @element player_list_container local player_list_container = Gui.element(function(event_trigger,parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } - - -- Set the container style - local style = container.style - style.vertically_stretchable = false + local container = Gui.container(parent,event_trigger,200) -- Draw the scroll table for the players local scroll_table = Gui.scroll_table(container,184,3) @@ -251,38 +216,24 @@ Gui.element(function(event_trigger,parent) scroll_table_style.padding = {1,0,1,2} -- Add the action bar - local action_bar = - container.add{ - name = 'action_bar', - type = 'frame', - style = 'subfooter_frame' - } + local action_bar = Gui.footer(container,nil,nil,false,'action_bar') -- Change the style of the action bar local action_bar_style = action_bar.style action_bar_style.height = 35 action_bar_style.padding = {1,3} - action_bar_style.use_header_filler = false - action_bar_style.horizontally_stretchable = true action_bar.visible = false -- Add the buttons to the action bar add_action_bar_buttons(action_bar) -- Add the reason bar - local reason_bar = - container.add{ - name = 'reason_bar', - type = 'frame', - style = 'subfooter_frame' - } + local reason_bar = Gui.footer(container,nil,nil,false,'reason_bar') -- Change the style of the reason bar local reason_bar_style = reason_bar.style reason_bar_style.height = 35 reason_bar_style.padding = {-1,3} - reason_bar_style.use_header_filler = false - reason_bar_style.horizontally_stretchable = true reason_bar.visible = false -- Add the text entry for the reason bar @@ -304,27 +255,24 @@ Gui.element(function(event_trigger,parent) reason_confirm(reason_bar) -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow(true) --- Button on the top flow used to toggle the player list container --- @element task_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'entity/character', - tooltip = {'player-list.main-tooltip'}, - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +-- @element toggle_left_element +Gui.left_toolbar_button('entity/character', {'player-list.main-tooltip'}, player_list_container, function(player) return Roles.player_allowed(player,'gui/player-list') end) -:on_click(function(player,_,_) - Gui.toggle_left_element(player, player_list_container) -end) + +-- Get caption and tooltip format for a player +local function get_time_formats(online_time,afk_time) + local tick = game.tick > 0 and game.tick or 1 + local percent = math.round(online_time/tick,3)*100 + local caption = format_time(online_time) + local tooltip = {'player-list.afk-time', percent, format_time(afk_time,{minutes=true,long=true})} + return caption, tooltip +end -- Get the player time to be used to update time label local function get_player_times() @@ -332,18 +280,19 @@ local function get_player_times() local player_times = {} for _, player in pairs(game.connected_players) do ctn = ctn + 1 - local tick = game.tick > 0 and game.tick or 1 - local percent = math.round(player.online_time/tick,3)*100 + -- Add the player time details to the array + local caption, tooltip = get_time_formats(player.online_time, player.afk_time) player_times[ctn] = { element_name = 'player-time-'..player.index, - caption = format_time(player.online_time), - tooltip = {'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + caption = caption, + tooltip = tooltip } end return player_times end +-- Get a sorted list of all online players local function get_player_list_order() -- Sort all the online players into roles local players = {} @@ -358,20 +307,20 @@ local function get_player_list_order() -- Sort the players from roles into a set order local ctn = 0 local player_list_order = {} - local tick = game.tick > 0 and game.tick or 1 for _,role_name in pairs(Roles.config.order) do if players[role_name] then for _,player in pairs(players[role_name]) do ctn = ctn + 1 - local percent = math.round(player.online_time/tick,3)*100 + -- Add the player data to the array + local caption, tooltip = get_time_formats(player.online_time, player.afk_time) player_list_order[ctn] = { name = player.name, index = player.index, tag = player.tag, role_name = role_name, chat_color = player.chat_color, - caption = format_time(player.online_time), - tooltip = {'player-list.afk-time',percent,format_time(player.afk_time,{minutes=true,long=true})} + caption = caption, + tooltip = tooltip } end end @@ -381,15 +330,15 @@ local function get_player_list_order() for i = 1, 10 do local online_time = math.random(1,tick) local afk_time = math.random(online_time-(tick/10),tick) - local percent = math.round(online_time/tick,3)*100 + local caption, tooltip = get_time_formats(online_time, afk_time) player_list_order[ctn+i] = { name='Player '..i, index=0-i, tag='', role_name = 'Fake Player', - chat_color=table.get_random_dictionary_entry(Colors), - caption = format_time(online_time), - tooltip = {'player-list.afk-time',percent,format_time(afk_time,{minutes=true,long=true})}, + chat_color = table.get_random_dictionary_entry(Colors), + caption = caption, + tooltip = tooltip } end]] @@ -400,8 +349,7 @@ end Event.on_nth_tick(1800,function() local player_times = get_player_times() for _,player in pairs(game.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table for _,player_time in pairs(player_times) do update_player_base(scroll_table,player_time) @@ -413,8 +361,7 @@ end) Event.add(defines.events.on_player_left_game,function(event) local remove_player = event.player for _,player in pairs(game.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table remove_player_base(scroll_table,remove_player) end @@ -424,8 +371,7 @@ end) local function redraw_player_list() local player_list_order = get_player_list_order() for _,player in pairs(game.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table scroll_table.clear() for _,next_player_data in ipairs(player_list_order) do @@ -441,8 +387,7 @@ Event.add(Roles.events.on_role_unassigned,redraw_player_list) --- When the action player is changed the action bar will update Store.watch(selected_player_store,function(value,player_name) local player = Game.get_player_from_any(player_name) - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table update_action_bar_buttons(frame.container.action_bar) for _,next_player in pairs(game.connected_players) do @@ -462,8 +407,7 @@ end) --- When the action name is changed the reason input will update Store.watch(selected_action_store,function(value,player_name) local player = Game.get_player_from_any(player_name) - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[player_list_container.name] + local frame = Gui.get_left_element(player,player_list_container) local element = frame.container.reason_bar if value then -- if there is a new value then check the player is still online diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index 69c2d9d9..b2490ed3 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -29,7 +29,8 @@ local function check_player_permissions(player,action) return false end - if config.progress[action..'_role_permission'] and not Roles.player_allowed(player,config.progress[action..'_role_permission']) then + if config.progress[action..'_role_permission'] + and not Roles.player_allowed(player,config.progress[action..'_role_permission']) then return false end @@ -45,12 +46,13 @@ Gui.element(function(_,parent,label_data) local data_fullname = data_subname and data_name..data_subname or data_name -- Add the name label - parent.add{ + local name_label = parent.add{ type = 'label', name = data_fullname..'-label', caption = {'rocket-info.data-caption-'..data_name,data_subname}, tooltip = {'rocket-info.data-tooltip-'..data_name,data_subname} } + name_label.style.padding = {0,2} --- Right aligned label to store the data local alignment = Gui.alignment(parent,nil,nil,data_fullname) @@ -61,6 +63,7 @@ Gui.element(function(_,parent,label_data) caption = label_data.value, tooltip = label_data.tooltip } + element.style.padding = {0,2} return element end) @@ -187,11 +190,7 @@ Gui.element{ sprite = 'utility/play', tooltip = {'rocket-info.toggle-rocket-tooltip'} } -:style{ - padding = -2, - width = 16, - height = 16 -} +:style(Gui.sprite_style(16)) :on_click(function(player,element,_) local rocket_silo_name = element.parent.name:sub(8) local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) @@ -214,11 +213,7 @@ Gui.element{ sprite = 'utility/center', tooltip = {'rocket-info.launch-tooltip'} } -:style{ - padding = -2, - width = 16, - height = 16 -} +:style(Gui.sprite_style(16,-1)) :on_click(function(player,element,_) local rocket_silo_name = element.parent.name:sub(8) local silo_data = Rockets.get_silo_data_by_name(rocket_silo_name) @@ -333,6 +328,7 @@ local function get_progress_data(force_name) silo_name = silo_data.name, remove = true }) + else -- Get the progress caption and tooltip local progress_color = Colors.white @@ -430,12 +426,8 @@ Gui.element{ hovered_sprite = 'utility/expand', tooltip = {'rocket-info.toggle-section-tooltip'} } -:style{ - padding = -2, - height = 20, - width = 20 -} -:on_click(function(player,element,_) +:style(Gui.sprite_style(20)) +:on_click(function(_,element,_) local header_flow = element.parent local flow_name = header_flow.caption local flow = header_flow.parent.parent[flow_name] @@ -479,33 +471,13 @@ end) -- @element rocket_list_container local rocket_list_container = Gui.element(function(event_trigger,parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } + local container = Gui.container(parent,event_trigger,200) -- Set the container style local style = container.style - style.vertically_stretchable = false style.padding = 0 - local player = Gui.get_player_from_element(parent) local force_name = player.force.name -- Draw stats section @@ -525,37 +497,27 @@ Gui.element(function(event_trigger,parent) if check_player_permissions(player,'toggle_active') then col_count = col_count+1 end local progress = section(container,'progress',col_count) -- Label used when there are no active silos - progress.add{ + local no_silos = progress.add{ type = 'label', name = 'no_silos', caption = {'rocket-info.progress-no-silos'} - } + } + no_silos.style.padding = {1,2} update_build_progress(progress,get_progress_data(force_name)) end -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow(function(player) return player.force.rockets_launched > 0 and Roles.player_allowed(player,'gui/rocket-info') end) --- Button on the top flow used to toggle the container --- @element rocket_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'entity/rocket-silo', - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +-- @element toggle_left_element +Gui.left_toolbar_button('entity/rocket-silo', {'rocket-info.main-tooltip'}, rocket_list_container, function(player) return Roles.player_allowed(player,'gui/rocket-info') end) -:on_click(function(player,_,_) - Gui.toggle_left_element(player, rocket_list_container) -end) --- Update the gui for all players on a force local function update_rocket_gui_all(force_name) @@ -563,8 +525,7 @@ local function update_rocket_gui_all(force_name) local milestones = get_milestone_data(force_name) local progress = get_progress_data(force_name) for _,player in pairs(game.forces[force_name].players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[rocket_list_container.name] + local frame = Gui.get_left_element(player,rocket_list_container) local container = frame.container update_data_labels(container.stats.table,stats) update_data_labels(container.milestones.table,milestones) @@ -587,8 +548,7 @@ end) local function update_rocket_gui_progress(force_name) local progress = get_progress_data(force_name) for _,player in pairs(game.forces[force_name].players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[rocket_list_container.name] + local frame = Gui.get_left_element(player,rocket_list_container) local container = frame.container update_build_progress(container.progress.table,progress) end @@ -616,8 +576,7 @@ Event.add(defines.events.on_robot_built_entity,on_built) --- Redraw the progress section on role change local function role_update_event(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local container = left_flow[rocket_list_container.name].container + local container = Gui.get_left_element(player,rocket_list_container).container local progress = container.progress if config.progress.show_progress then progress.destroy() diff --git a/modules/gui/science-info.lua b/modules/gui/science-info.lua index a3d74b33..0fd224fb 100644 --- a/modules/gui/science-info.lua +++ b/modules/gui/science-info.lua @@ -47,7 +47,9 @@ Gui.element(function(_,parent,production_label_data) } -- Change the style - surfix_element.style.font_color = color + local surfix_element_style = surfix_element.style + surfix_element_style.font_color = color + surfix_element_style.right_margin = 1 -- Return the value label return element @@ -119,8 +121,6 @@ Gui.element(function(_,parent,science_pack_data) type = 'frame', style = 'bordered_frame' } - - -- Change the style of the delta flow delta_flow.style.padding = {0,3} -- Draw the delta flow table @@ -130,8 +130,6 @@ Gui.element(function(_,parent,science_pack_data) type = 'table', column_count = 2 } - - -- Change the style of the delta flow table delta_table.style.padding = 0 -- Draw the production labels @@ -223,9 +221,9 @@ local function get_eta_label_data(player) return { research = false } end + local limit local progress = force.research_progress local remaining = research.research_unit_count*(1-progress) - local limit -- Check for the limiting science pack for _,ingredient in pairs(research.research_unit_ingredients) do @@ -266,40 +264,14 @@ local science_info_container = Gui.element(function(event_trigger,parent) local player = Gui.get_player_from_element(parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } - - -- Set the container style - local style = container.style - style.vertically_stretchable = false + local container = Gui.container(parent,event_trigger,200) -- Draw the header - Gui.header( - container, - {'science-info.main-caption'}, - {'science-info.main-tooltip'} - ) + Gui.header(container, {'science-info.main-caption'}, {'science-info.main-tooltip'}) -- Draw the scroll table for the tasks - local scroll_table = Gui.scroll_table(container,185,4) + local scroll_table = Gui.scroll_table(container,178,4) -- Draw the no packs label local no_packs_label = @@ -318,20 +290,7 @@ Gui.element(function(event_trigger,parent) -- Add the footer and eta if config.show_eta then -- Draw the footer - local footer = Gui.header( - container, - {'science-info.eta-caption'}, - {'science-info.eta-tooltip'}, - true, - 'footer' - ) - - -- Set the style - footer.parent.style = 'subheader_frame' - local footer_style = footer.parent.style - footer_style.padding = {2,4} - footer_style.use_header_filler = false - footer_style.horizontally_stretchable = true + local footer = Gui.footer(container, {'science-info.eta-caption'}, {'science-info.eta-tooltip'}, true) -- Draw the eta label local eta_label = @@ -354,27 +313,15 @@ Gui.element(function(event_trigger,parent) end -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow() --- Button on the top flow used to toggle the task list container --- @element task_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'entity/lab', - tooltip = {'science-info.main-tooltip'}, - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +-- @element toggle_left_element +Gui.left_toolbar_button('entity/lab', {'science-info.main-tooltip'}, science_info_container, function(player) return Roles.player_allowed(player,'gui/science-info') end) -:on_click(function(player,_,_) - Gui.toggle_left_element(player, science_info_container) -end) --- Updates the gui every 1 second Event.on_nth_tick(60,function() @@ -382,8 +329,7 @@ Event.on_nth_tick(60,function() local force_eta_data = {} for _,player in pairs(game.connected_players) do local force_name = player.force.name - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[science_info_container.name] + local frame = Gui.get_left_element(player,science_info_container) local container = frame.container -- Update the science packs diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index 68baedae..b1ef31e4 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -11,6 +11,12 @@ local config = require 'config.tasks' --- @dep config.tasks local format_time,table_keys = ext_require('expcore.common','format_time','table_keys') --- @dep expcore.common local Tasks = require 'modules.control.tasks' --- @dep modules.control.tasks +-- Styles used for sprite buttons +local Styles = { + sprite20 = Gui.sprite_style(20), + sprite22 = Gui.sprite_style(20, nil, { right_margin = -3 }) +} + --- If a player is allowed to use the edit buttons local function check_player_permissions(player,task) if task then @@ -60,11 +66,7 @@ Gui.element{ tooltip = {'task-list.add-tooltip'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(player,_,_) Tasks.add_task(player.force.name,nil,player.name) end) @@ -78,11 +80,7 @@ Gui.element{ tooltip = {'task-list.edit-tooltip-none'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(player,element,_) local task_id = element.parent.name:sub(6) Tasks.set_editing(task_id,player.name,true) @@ -97,11 +95,7 @@ Gui.element{ tooltip = {'task-list.discard-tooltip'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(_,element,_) local task_id = element.parent.name:sub(6) Tasks.remove_task(task_id) @@ -112,22 +106,16 @@ end) local add_task_base = Gui.element(function(_,parent,task_id) -- Add the task number label - parent.add{ + local task_number = parent.add{ name = 'count-'..task_id, type = 'label', caption = '0)' } + task_number.style.left_margin = 1 -- Add a flow which will contain the task message and edit buttons - local task_flow = - parent.add{ - name = task_id, - type = 'flow', - } - - -- Set the padding on the task flow - local task_flow_style = task_flow.style - task_flow_style.padding = 0 + local task_flow = parent.add{ name = task_id, type = 'flow', } + task_flow.style.padding = 0 -- Add the two edit buttons outside the task flow local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..task_id) @@ -155,12 +143,7 @@ Gui.element{ tooltip = {'task-list.confirm-tooltip'}, style = 'shortcut_bar_button_green' } -:style{ - padding = -2, - right_margin = -3, - height = 22, - width = 22 -} +:style(Styles.sprite22) :on_click(function(player,element,_) local task_id = element.parent.name local new_message = element.parent[task_editing.name].text @@ -177,12 +160,7 @@ Gui.element{ tooltip = {'task-list.cancel-tooltip'}, style = 'shortcut_bar_button_red' } -:style{ - padding = -2, - right_margin = -3, - height = 22, - width = 22 -} +:style(Styles.sprite22) :on_click(function(player,element,_) local task_id = element.parent.name Tasks.set_editing(task_id,player.name) @@ -203,11 +181,6 @@ Gui.element(function(event_trigger,parent,task) clear_and_focus_on_right_click = true } - -- Change the style - local style = element.style - style.maximal_width = 110 - style.height = 20 - -- Add the edit buttons cancel_edit(parent) confirm_edit(parent) @@ -215,6 +188,10 @@ Gui.element(function(event_trigger,parent,task) -- Return the element return element end) +:style{ + maximal_width = 110, + height = 20 +} :on_confirmed(function(player,element,_) local task_id = element.parent.name local new_message = element.text @@ -229,24 +206,18 @@ Gui.element(function(_,parent,task) local message = task.message local last_edit_name = task.last_edit_name local last_edit_time = task.last_edit_time - -- Draw the element - local element = - parent.add{ + return parent.add{ name = task_editing.name, type = 'label', caption = message, tooltip = {'task-list.last-edit', last_edit_name, format_time(last_edit_time)} } - - -- Change the style - local style = element.style - style.single_line = false - style.maximal_width = 150 - - -- Return the element - return element end) +:style{ + single_line = false, + maximal_width = 150 +} --- Updates a task for a player local function update_task(player,task_table,task_id) @@ -308,10 +279,12 @@ local function update_task(player,task_table,task_id) edit_task_element.enabled = false task_flow.clear() task_editing(task_flow,task).focus() + task_table.parent.scroll_to_element(task_flow,'top-third') end end +-- Update all the tasks for a player local function update_all_tasks(player,scroll_table) local task_ids = Tasks.get_force_task_ids(player.force.name) if #task_ids > 0 then @@ -325,30 +298,8 @@ end -- @element task_list_container local task_list_container = Gui.element(function(event_trigger,parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } - - -- Set the container style - local style = container.style - style.vertically_stretchable = false + local container = Gui.container(parent,event_trigger,200) -- Draw the header local header = Gui.header( @@ -364,7 +315,7 @@ Gui.element(function(event_trigger,parent) add_new_task_element.visible = check_player_permissions(player) -- Draw the scroll table for the tasks - local scroll_table = Gui.scroll_table(container,185,3) + local scroll_table = Gui.scroll_table(container,190,3) scroll_table.draw_horizontal_lines = true scroll_table.vertical_centering = false @@ -397,7 +348,7 @@ Gui.element(function(event_trigger,parent) end -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow(function(player) local task_ids = Tasks.get_force_task_ids(player.force.name) @@ -405,22 +356,10 @@ end) end) --- Button on the top flow used to toggle the task list container --- @element task_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'utility/not_enough_repair_packs_icon', - tooltip = {'task-list.main-tooltip'}, - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +-- @element toggle_left_element +Gui.left_toolbar_button('utility/not_enough_repair_packs_icon', {'task-list.main-tooltip'}, task_list_container, function(player) return Roles.player_allowed(player,'gui/task-list') end) -:on_click(function(player,_,_) - Gui.toggle_left_element(player, task_list_container) -end) --- When a new task is added it will udpate the task list for everyone on that force Tasks.on_update(function(task,task_id,removed_task) @@ -435,8 +374,7 @@ Tasks.on_update(function(task,task_id,removed_task) -- Update the task for all the players on the force local task_ids = Tasks.get_force_task_ids(force.name) for _,player in pairs(force.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[task_list_container.name] + local frame = Gui.get_left_element(player,task_list_container) local scroll_table = frame.container.scroll.table -- Update the task that was changed @@ -455,8 +393,7 @@ end) --- Update the tasks when the player joins Event.add(defines.events.on_player_joined_game,function(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[task_list_container.name] + local frame = Gui.get_left_element(player,task_list_container) local scroll_table = frame.container.scroll.table update_all_tasks(player,scroll_table) end) @@ -464,8 +401,7 @@ end) --- Makes sure the right buttons are present when roles change local function role_update_event(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local container = left_flow[task_list_container.name].container + local container = Gui.get_left_element(player,task_list_container).container -- Update the tasks, incase the user can now edit them local scroll_table = container.scroll.table diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index f39c562d..e51e01c3 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -31,6 +31,13 @@ Global.register(keep_gui_open,function(tbl) keep_gui_open = tbl end) +-- Styles used for sprite buttons +local Styles = { + sprite20 = Gui.sprite_style(20), + sprite22 = Gui.sprite_style(20, nil, { right_margin = -3 }), + sprite32 = { height = 32, width = 32, left_margin = 1 } +} + --- Returns if a player is allowed to edit the given warp --- If a player is allowed to use the edit buttons local function check_player_permissions(player,action,warp) @@ -71,11 +78,7 @@ Gui.element{ tooltip = {'warp-list.add-tooltip'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(player,element) -- Add the new warp local force_name = player.force.name @@ -95,11 +98,7 @@ Gui.element{ tooltip = {'warp-list.discard-tooltip'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(_,element) local warp_id = element.parent.name:sub(6) Warps.remove_warp(warp_id) @@ -114,11 +113,7 @@ Gui.element{ tooltip = {'warp-list.edit-tooltip-none'}, style = 'tool_button' } -:style{ - padding = -2, - height = 20, - width = 20 -} +:style(Styles.sprite20) :on_click(function(player,element) local warp_id = element.parent.name:sub(6) Warps.set_editing(warp_id,player.name,true) @@ -135,18 +130,10 @@ Gui.element(function(_,parent,warp_id) type = 'flow', caption = warp_id } - - -- Change the style of the flow icon_flow.style.padding = 0 -- Add a flow which will contain the warp name and edit buttons - local warp_flow = - parent.add{ - name = warp_id, - type = 'flow', - } - - -- Set the padding on the warp flow + local warp_flow = parent.add{ type = 'flow', name = warp_id } warp_flow.style.padding = 0 -- Add the two edit buttons outside the warp flow @@ -176,12 +163,7 @@ Gui.element{ tooltip = {'warp-list.confirm-tooltip'}, style = 'shortcut_bar_button_green' } -:style{ - padding = -2, - right_margin = -3, - height = 22, - width = 22 -} +:style(Styles.sprite22) :on_click(function(player,element) local warp_id = element.parent.name local warp_name = element.parent[warp_editing.name].text @@ -199,12 +181,7 @@ Gui.element{ tooltip = {'warp-list.cancel-tooltip'}, style = 'shortcut_bar_button_red' } -:style{ - padding = -2, - right_margin = -3, - height = 22, - width = 22 -} +:style(Styles.sprite22) :on_click(function(player,element) local warp_id = element.parent.name Warps.set_editing(warp_id,player.name) @@ -225,11 +202,6 @@ Gui.element(function(event_trigger,parent,warp) clear_and_focus_on_right_click = true } - -- Change the style - local style = element.style - style.maximal_width = 110 - style.height = 20 - -- Add the edit buttons cancel_edit(parent) confirm_edit(parent) @@ -237,6 +209,10 @@ Gui.element(function(event_trigger,parent,warp) -- Return the element return element end) +:style{ + maximal_width = 110, + height = 20 +} :on_confirmed(function(player,element,_) local warp_id = element.parent.name local warp_name = element.text @@ -249,27 +225,20 @@ end) -- @element warp_label local warp_label = Gui.element(function(event_trigger,parent,warp) - local name = warp.name local last_edit_name = warp.last_edit_name local last_edit_time = warp.last_edit_time - -- Draw the element - local element = - parent.add{ + return parent.add{ name = event_trigger, type = 'label', - caption = name, + caption = warp.name, tooltip = {'warp-list.last-edit',last_edit_name,format_time(last_edit_time)} } - - -- Change the style - local style = element.style - style.single_line = false - style.maximal_width = 150 - - -- Return the element - return element end) +:style{ + single_line = false, + maximal_width = 150 +} :on_click(function(player,element,_) local warp_id = element.parent.name local warp = Warps.get_warp(warp_id) @@ -283,25 +252,16 @@ end) warp_icon_button = Gui.element(function(event_trigger,parent,warp) local warp_position = warp.position - -- Draw the element - local element = - parent.add{ + return parent.add{ name = event_trigger, type = 'sprite-button', sprite = 'item/'..warp.icon, tooltip = {'warp-list.goto-tooltip',warp_position.x,warp_position.y}, style = 'quick_bar_slot_button' } - - -- Change the style - local style = element.style - style.height = 32 - style.width = 32 - - -- Return the element - return element end) +:style(Styles.sprite32) :on_click(function(player,element,_) local warp_id = element.parent.caption Warps.teleport_player(warp_id,player) @@ -316,27 +276,16 @@ end) --- Editing state for the warp icon, chose elem used to chosse icon -- @element warp_icon_editing local warp_icon_editing = -Gui.element(function(event_trigger,parent,warp) - local warp_icon = warp.icon - - -- Draw the element - local element = - parent.add{ +Gui.element(function(_,parent,warp) + return parent.add{ name = warp_icon_button.name, type = 'choose-elem-button', elem_type = 'item', - item = warp_icon, + item = warp.icon, tooltip = {'warp-list.goto-edit'}, } - - -- Change the style - local style = element.style - style.height = 32 - style.width = 32 - - -- Return the element - return element end) +:style(Styles.sprite32) --- This timer controls when a player is able to warp, eg every 60 seconds -- @element warp_timer @@ -421,12 +370,14 @@ local function update_warp(player,warp_table,warp_id) edit_warp_element.enabled = false warp_flow.clear() warp_editing(warp_flow,warp).focus() + warp_table.parent.scroll_to_element(warp_flow,'top-third') icon_flow.clear() warp_icon_editing(icon_flow,warp) end end +-- Update all the warps for a player local function update_all_warps(player,warp_table) local warp_ids = Warps.get_force_warp_ids(player.force.name) if #warp_ids > 0 then @@ -440,30 +391,8 @@ end -- @element warp_list_container local warp_list_container = Gui.element(function(event_trigger,parent) - -- Draw the external container - local frame = - parent.add{ - name = event_trigger, - type = 'frame' - } - - -- Set the frame style - local frame_style = frame.style - frame_style.padding = 2 - frame_style.minimal_width = 200 - -- Draw the internal container - local container = - frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } - - -- Set the container style - local style = container.style - style.vertically_stretchable = false + local container = Gui.container(parent,event_trigger,200) -- Draw the header local header = Gui.header( @@ -479,7 +408,7 @@ Gui.element(function(event_trigger,parent) add_new_warp_element.visible = check_player_permissions(player,'allow_add_warp') -- Draw the scroll table for the warps - local scroll_table = Gui.scroll_table(container,258,3) + local scroll_table = Gui.scroll_table(container,250,3) -- Change the style of the scroll table local scroll_table_style = scroll_table.style @@ -501,7 +430,7 @@ Gui.element(function(event_trigger,parent) update_all_warps(player,scroll_table) -- Return the exteral container - return frame + return container.parent end) :add_to_left_flow() @@ -537,8 +466,7 @@ Warps.on_update(function(warp,_,removed_warp) -- Update the gui for selected players local warp_ids = Warps.get_force_warp_ids(force.name) for _,player in pairs(force.connected_players) do - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local scroll_table = frame.container.scroll.table -- Update the gui @@ -552,8 +480,7 @@ end) --- Update the warps when the player joins Event.add(defines.events.on_player_joined_game,function(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local scroll_table = frame.container.scroll.table update_all_warps(player,scroll_table) end) @@ -561,8 +488,7 @@ end) --- Makes sure the right buttons are present when roles change local function role_update_event(event) local player = game.players[event.player_index] - local left_flow = Gui.get_left_flow(player) - local container = left_flow[warp_list_container.name].container + local container = Gui.get_left_element(player,warp_list_container).container -- Update the warps, incase the user can now edit them local scroll_table = container.scroll.table @@ -592,8 +518,7 @@ Store.watch(player_in_range_store,function(value,player_name) end -- Get the warp table - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local scroll_table = frame.container.scroll.table -- Check if the buttons should be active @@ -621,8 +546,7 @@ Store.watch(player_warp_cooldown_store,function(value,player_name,old_value) if value == old_value then return end -- Get the progress bar element local player = game.players[player_name] - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local warp_timer_element = frame.container[warp_timer.name] -- Set the progress @@ -702,8 +626,7 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing),function() end -- Change the enabled state of the add warp button - local left_flow = Gui.get_left_flow(player) - local frame = left_flow[warp_list_container.name] + local frame = Gui.get_left_element(player,warp_list_container) local add_warp_element = frame.container.header.alignment[add_new_warp.name] local was_able_to_make_warp = add_warp_element.enabled local can_make_warp = closest_distance > mr2 From 2a5d30961b252a65a9d70f2627c608c000a801c1 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 16 Feb 2020 16:27:34 +0000 Subject: [PATCH 23/81] Added redmew compatibilty --- config/_file_loader.lua | 2 +- expcore/gui.lua | 11 +- modules/commands/debug.lua | 2 +- modules/gui/debug/event_view.lua | 86 ++++++++-- modules/gui/debug/expcore_gui_view.lua | 128 +++++++++++++++ modules/gui/debug/expcore_store_view.lua | 4 +- modules/gui/debug/main_view.lua | 3 +- utils/gui.lua | 198 ++--------------------- 8 files changed, 230 insertions(+), 204 deletions(-) create mode 100644 modules/gui/debug/expcore_gui_view.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index f7ad4c42..1b21e619 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -44,7 +44,7 @@ return { 'modules.gui.warp-list', 'modules.gui.task-list', 'modules.gui.player-list', - --'modules.commands.debug', + 'modules.commands.debug', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.expcore-commands.auth_roles', -- commands must be allowed via the role config diff --git a/expcore/gui.lua b/expcore/gui.lua index e6874e31..de0cd8f9 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -87,6 +87,9 @@ local Gui = { --- An index used for debuging to find the file where different elements where registered -- @table file_paths file_paths = {}, + --- An index used for debuging to show the raw data used to define an element + -- @table debug_info + debug_info = {}, --- The element prototype which is returned from Gui.element -- @table _prototype_element _prototype_element = {}, @@ -154,14 +157,17 @@ function Gui.element(element_define) Gui.uid = uid local name = tostring(uid) element.name = name + Gui.debug_info[name] = { draw = 'None', style = 'None', events = {} } -- Add the defination function if type(element_define) == 'table' then + Gui.debug_info[name].draw = element_define element_define.name = name element._draw = function(_,parent) return parent.add(element_define) end else + Gui.debug_info[name].draw = 'Function' element._draw = element_define end @@ -206,12 +212,14 @@ end) function Gui._prototype_element:style(style_define) -- Add the defination function if type(style_define) == 'table' then + Gui.debug_info[self.name].style = style_define self._style = function(style) for key,value in pairs(style_define) do style[key] = value end end else + Gui.debug_info[self.name].style = 'Function' self._style = style_define end @@ -281,6 +289,7 @@ local function event_handler_factory(event_name) Event.add(event_name, general_event_handler) return function(self,handler) + table.insert(Gui.debug_info[self.name].events,debug.getinfo(1, "n").name) self[event_name] = handler return self end @@ -331,7 +340,7 @@ Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events. --- Called when LuaGuiElement text is changed by the player. -- @tparam function handler the event handler which will be called -Gui._prototype_element.on_text_change = event_handler_factory(defines.events.on_gui_text_changed) +Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed) --- Called when LuaGuiElement slider value is changed (related to the slider element). -- @tparam function handler the event handler which will be called diff --git a/modules/commands/debug.lua b/modules/commands/debug.lua index f0be73ba..e29786a6 100644 --- a/modules/commands/debug.lua +++ b/modules/commands/debug.lua @@ -9,6 +9,6 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands --- Opens the debug pannel for viewing tables. -- @command debug Commands.new_command('debug','Opens the debug pannel for viewing tables.') -:register(function(player,raw) +:register(function(player) DebugView.open_dubug(player) end) \ No newline at end of file diff --git a/modules/gui/debug/event_view.lua b/modules/gui/debug/event_view.lua index bc372007..cae93e60 100644 --- a/modules/gui/debug/event_view.lua +++ b/modules/gui/debug/event_view.lua @@ -1,7 +1,7 @@ -local Event = require 'utils.event' --- @dep utils.event -local table = require 'utils.table' --- @dep utils.table -local Gui = require 'utils.gui' --- @dep utils.gui -local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model +local Event = require 'utils.event' +local table = require 'utils.table' +local Gui = require 'utils.gui' +local Model = require 'modules.gui.debug.model' local format = string.format local insert = table.insert @@ -19,13 +19,16 @@ local name_lookup = {} -- GUI names local checkbox_name = Gui.uid_name() +local filter_name = Gui.uid_name() +local clear_filter_name = Gui.uid_name() -- global tables local enabled = {} local last_events = {} global.debug_event_view = { enabled = enabled, - last_events = last_events + last_events = last_events, + filter = '' } function Public.on_open_debug() @@ -90,24 +93,73 @@ end table.sort(grid_builder) -function Public.show(container) - local main_frame_flow = container.add({type = 'flow', direction = 'vertical'}) - local scroll_pane = main_frame_flow.add({type = 'scroll-pane'}) - local gui_table = scroll_pane.add({type = 'table', column_count = 3, draw_horizontal_lines = true}) - +local function redraw_event_table(gui_table, filter) for _, event_name in pairs(grid_builder) do - local index = events[event_name] - gui_table.add({type = 'flow'}).add { - name = checkbox_name, - type = 'checkbox', - state = enabled[index] or false, - caption = event_name - } + if filter == '' or event_name:find(filter) then + local index = events[event_name] + gui_table.add({type = 'flow'}).add { + name = checkbox_name, + type = 'checkbox', + state = enabled[index] or false, + caption = event_name + } + end end end +function Public.show(container) + local filter = global.debug_event_view.filter + + local main_frame_flow = container.add({type = 'flow', direction = 'vertical'}) + + local filter_flow = main_frame_flow.add({type = 'flow', direction = 'horizontal'}) + filter_flow.add({type = 'label', caption = 'filter'}) + local filter_textfield = filter_flow.add({type = 'textfield', name = filter_name, text = filter}) + local clear_button = filter_flow.add({type = 'button', name = clear_filter_name, caption = 'clear'}) + + local scroll_pane = main_frame_flow.add({type = 'scroll-pane'}) + local gui_table = scroll_pane.add({type = 'table', column_count = 3, draw_horizontal_lines = true}) + + Gui.set_data(filter_textfield, gui_table) + Gui.set_data(clear_button, {gui_table = gui_table, filter_textfield = filter_textfield}) + + redraw_event_table(gui_table, filter) +end + Gui.on_checked_state_changed(checkbox_name, on_gui_checked_state_changed) +Gui.on_text_changed( + filter_name, + function(event) + local element = event.element + local gui_table = Gui.get_data(element) + + local filter = element.text:gsub(' ', '_') + + global.debug_event_view.filter = filter + element.text = filter + + gui_table.clear() + redraw_event_table(gui_table, filter) + end +) + +Gui.on_click( + clear_filter_name, + function(event) + local element = event.element + local data = Gui.get_data(element) + local filter_textfield = data.filter_textfield + local gui_table = data.gui_table + + filter_textfield.text = '' + global.debug_event_view.filter = '' + + gui_table.clear() + redraw_event_table(gui_table, '') + end +) + -- Event registers (TODO: turn to removable hooks.. maybe) for name, id in pairs(events) do name_lookup[id] = name diff --git a/modules/gui/debug/expcore_gui_view.lua b/modules/gui/debug/expcore_gui_view.lua new file mode 100644 index 00000000..cf95e894 --- /dev/null +++ b/modules/gui/debug/expcore_gui_view.lua @@ -0,0 +1,128 @@ +local Gui = require 'utils.gui' --- @dep utils.gui +local ExpGui = require 'expcore.gui' --- @dep utils.global +local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model + +local dump = Model.dump +local dump_text = Model.dump_text +local concat = table.concat + +local Public = {} + +local header_name = Gui.uid_name() +local left_panel_name = Gui.uid_name() +local right_panel_name = Gui.uid_name() +local input_text_box_name = Gui.uid_name() +local refresh_name = Gui.uid_name() + +Public.name = 'Elements' + +function Public.show(container) + local main_flow = container.add {type = 'flow', direction = 'horizontal'} + + local left_panel = main_flow.add {type = 'scroll-pane', name = left_panel_name} + local left_panel_style = left_panel.style + left_panel_style.width = 300 + + for element_id, file_path in pairs(ExpGui.file_paths) do + local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = element_id..' - '..file_path} + Gui.set_data(header, element_id) + end + + local right_flow = main_flow.add {type = 'flow', direction = 'vertical'} + + local right_top_flow = right_flow.add {type = 'flow', direction = 'horizontal'} + + local input_text_box = right_top_flow.add {type = 'text-box', name = input_text_box_name} + local input_text_box_style = input_text_box.style + input_text_box_style.horizontally_stretchable = true + input_text_box_style.height = 32 + input_text_box_style.maximal_width = 1000 + + local refresh_button = + right_top_flow.add {type = 'sprite-button', name = refresh_name, sprite = 'utility/reset', tooltip = 'refresh'} + local refresh_button_style = refresh_button.style + refresh_button_style.width = 32 + refresh_button_style.height = 32 + + local right_panel = right_flow.add {type = 'text-box', name = right_panel_name} + right_panel.read_only = true + right_panel.selectable = true + + local right_panel_style = right_panel.style + right_panel_style.vertically_stretchable = true + right_panel_style.horizontally_stretchable = true + right_panel_style.maximal_width = 1000 + right_panel_style.maximal_height = 1000 + + local data = { + right_panel = right_panel, + input_text_box = input_text_box, + selected_header = nil + } + + Gui.set_data(input_text_box, data) + Gui.set_data(left_panel, data) + Gui.set_data(refresh_button, data) +end + +Gui.on_click( + header_name, + function(event) + local element = event.element + local element_id = Gui.get_data(element) + + local left_panel = element.parent.parent + local data = Gui.get_data(left_panel) + local right_panel = data.right_panel + local selected_header = data.selected_header + local input_text_box = data.input_text_box + + if selected_header then + selected_header.style.font_color = Color.white + end + + element.style.font_color = Color.orange + data.selected_header = element + + input_text_box.text = concat {'Gui.defines[', element_id, ']'} + input_text_box.style.font_color = Color.black + + local content = dump(ExpGui.debug_info[element_id]) or 'nil' + right_panel.text = content + end +) + +local function update_dump(text_input, data, player) + local suc, ouput = dump_text(text_input.text, player) + if not suc then + text_input.style.font_color = Color.red + else + text_input.style.font_color = Color.black + data.right_panel.text = ouput + end +end + +Gui.on_text_changed( + input_text_box_name, + function(event) + local element = event.element + local data = Gui.get_data(element) + + update_dump(element, data, event.player) + end +) + +Gui.on_click( + refresh_name, + function(event) + local element = event.element + local data = Gui.get_data(element) + + local input_text_box = data.input_text_box + + update_dump(input_text_box, data, event.player) + end +) + +return Public diff --git a/modules/gui/debug/expcore_store_view.lua b/modules/gui/debug/expcore_store_view.lua index 2d115992..300acc2d 100644 --- a/modules/gui/debug/expcore_store_view.lua +++ b/modules/gui/debug/expcore_store_view.lua @@ -24,8 +24,8 @@ function Public.show(container) local left_panel_style = left_panel.style left_panel_style.width = 300 - for store_id, token_name in pairs(Store.file_paths) do - local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = store_id..' - '..token_name} + for store_id, file_path in pairs(Store.file_paths) do + local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = store_id..' - '..file_path} Gui.set_data(header, store_id) end diff --git a/modules/gui/debug/main_view.lua b/modules/gui/debug/main_view.lua index 3c286a46..9807329c 100644 --- a/modules/gui/debug/main_view.lua +++ b/modules/gui/debug/main_view.lua @@ -6,6 +6,7 @@ local Public = {} local pages = { require 'modules.gui.debug.redmew_global_view', require 'modules.gui.debug.expcore_store_view', + require 'modules.gui.debug.expcore_gui_view', require 'modules.gui.debug.global_view', require 'modules.gui.debug.package_view', require 'modules.gui.debug._g_view', @@ -31,7 +32,7 @@ function Public.open_dubug(player) return end - frame = center.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3001', direction = 'vertical'} + frame = center.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3002', direction = 'vertical'} local frame_style = frame.style frame_style.height = 600 frame_style.width = 900 diff --git a/utils/gui.lua b/utils/gui.lua index 764037e0..36fc1d61 100644 --- a/utils/gui.lua +++ b/utils/gui.lua @@ -1,11 +1,7 @@ -local Token = require 'utils.token' --- @dep utils.token -local Event = require 'utils.event' --- @dep utils.event -local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global -local mod_gui = require 'mod-gui' --- @dep mod-gui +local ExpGui = require 'expcore.gui' --- @dep expcore.gui local Gui = {} - local data = {} Global.register( @@ -15,12 +11,9 @@ Global.register( end ) -local top_elements = {} -local on_visible_handlers = {} -local on_pre_hidden_handlers = {} - function Gui.uid_name() - return tostring(Token.uid()) + local new_element = ExpGui.element() + return new_element.name end -- Associates data with the LuaGuiElement. If data is nil then removes the data @@ -75,219 +68,62 @@ function Gui.clear(element) element.clear() end -local function handler_factory(event_id) - local handlers - - local function on_event(event) - local element = event.element - if not element or not element.valid then - return - end - - local handler = handlers[element.name] - if not handler then - return - end - - local player = Game.get_player_by_index(event.player_index) - if not player or not player.valid then - return - end - event.player = player - - handler(event) - end - +local function handler_factory(event_name) return function(element_name, handler) - if not handlers then - handlers = {} - Event.add(event_id, on_event) - end - - handlers[element_name] = handler + local element = ExpGui.defines[element_name] + if not element then return end + element[event_name](element,function(_,_,event) + handler(event) + end) end end -local function custom_handler_factory(handlers) - return function(element_name, handler) - handlers[element_name] = handler - end -end - -local function custom_raise(handlers, element, player) - local handler = handlers[element.name] - if not handler then - return - end - - handler({element = element, player = player}) -end - -- Register a handler for the on_gui_checked_state_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_checked_state_changed = handler_factory(defines.events.on_gui_checked_state_changed) +Gui.on_checked_state_changed = handler_factory('on_checked_changed') -- Register a handler for the on_gui_click event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_click = handler_factory(defines.events.on_gui_click) +Gui.on_click = handler_factory('on_click') -- Register a handler for the on_gui_closed event for a custom LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_custom_close = handler_factory(defines.events.on_gui_closed) +Gui.on_custom_close = handler_factory('on_closed') -- Register a handler for the on_gui_elem_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_elem_changed = handler_factory(defines.events.on_gui_elem_changed) +Gui.on_elem_changed = handler_factory('on_elem_changed') -- Register a handler for the on_gui_selection_state_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_selection_state_changed = handler_factory(defines.events.on_gui_selection_state_changed) +Gui.on_selection_state_changed = handler_factory('on_selection_changed') -- Register a handler for the on_gui_text_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_text_changed = handler_factory(defines.events.on_gui_text_changed) +Gui.on_text_changed = handler_factory('on_text_changed') -- Register a handler for the on_gui_value_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_value_changed = handler_factory(defines.events.on_gui_value_changed) - --- Register a handler for when the player shows the top LuaGuiElements with element_name. --- Assuming the element_name has been added with Gui.allow_player_to_toggle_top_element_visibility. --- Can only have one handler per element name. --- Guarantees that the element and the player are valid when calling the handler. --- Adds a player field to the event table. -Gui.on_player_show_top = custom_handler_factory(on_visible_handlers) - --- Register a handler for when the player hides the top LuaGuiElements with element_name. --- Assuming the element_name has been added with Gui.allow_player_to_toggle_top_element_visibility. --- Can only have one handler per element name. --- Guarantees that the element and the player are valid when calling the handler. --- Adds a player field to the event table. -Gui.on_pre_player_hide_top = custom_handler_factory(on_pre_hidden_handlers) - ---- Allows the player to show / hide this element. --- The element must be in Gui.get_top_element_flow(player) --- This function must be called in the control stage, i.e not inside an event. --- @param element_name This name must be globally unique. -function Gui.allow_player_to_toggle_top_element_visibility(element_name) - if _LIFECYCLE ~= _STAGE.control then - error('can only be called during the control stage', 2) - end - top_elements[#top_elements + 1] = element_name -end +Gui.on_value_changed = handler_factory('on_value_changed') --- Returns the flow where top elements can be added and will be effected by google visibility -- For the toggle to work it must be registed with Gui.allow_player_to_toggle_top_element_visibility(element_name) -- @tparam LuaPlayer player pointer to the player who has the gui -- @treturn LuaGuiElement the top element flow -function Gui.get_top_element_flow(player) - player = Game.get_player_from_any(player) - return mod_gui.get_button_flow(player) -end - -local toggle_button_name = Gui.uid_name() -Gui.top_toggle_button_name = toggle_button_name - -Event.add( - defines.events.on_player_created, - function(event) - local player = Game.get_player_by_index(event.player_index) - - if not player or not player.valid then - return - end - - local top = Gui.get_top_element_flow(player) - - local b = top.add { - type = 'button', - name = toggle_button_name, - style = mod_gui.button_style, - caption = '<', - tooltip = {'gui_util.button_tooltip'} - } - local style = b.style - style.width = 18 - style.height = 36 - style.left_padding = 0 - style.top_padding = 0 - style.right_padding = 0 - style.bottom_padding = 0 - style.font = 'default-small-bold' - end -) - -Gui.on_click( - toggle_button_name, - function(event) - local button = event.element - local player = event.player - local top = Gui.get_top_element_flow(player) - - if button.caption == '<' then - for i = 1, #top_elements do - local name = top_elements[i] - local ele = top[name] - if ele and ele.valid then - if ele.visible then - custom_raise(on_pre_hidden_handlers, ele, player) - ele.visible = false - end - end - end - - button.caption = '>' - button.style.height = 24 - else - for i = 1, #top_elements do - local name = top_elements[i] - local ele = top[name] - if ele and ele.valid then - if not ele.visible then - ele.visible = true - custom_raise(on_visible_handlers, ele, player) - end - end - end - - button.caption = '<' - button.style.height = 36 - end - end -) - -if _DEBUG then - local concat = table.concat - - local names = {} - Gui.names = names - - function Gui.uid_name() - local info = debug.getinfo(2, 'Sl') - local filepath = info.source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) - local line = info.currentline - - local token = tostring(Token.uid()) - - local name = concat {token, ' - ', filepath, ':line:', line} - names[token] = name - - return token - end -end +Gui.get_top_element_flow = ExpGui.get_top_flow return Gui \ No newline at end of file From 50213c71add32dceba365fd583a1b9b051772df4 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 16 Feb 2020 17:25:05 +0000 Subject: [PATCH 24/81] Added Async --- expcore/async.lua | 71 +++++++++++++++++++++++++++++++ expcore/permission_groups.lua | 27 +++++++----- expcore/roles.lua | 14 +++---- expcore/sudo.lua | 76 ---------------------------------- modules/commands/interface.lua | 2 +- 5 files changed, 95 insertions(+), 95 deletions(-) create mode 100644 expcore/async.lua delete mode 100644 expcore/sudo.lua diff --git a/expcore/async.lua b/expcore/async.lua new file mode 100644 index 00000000..21ae7080 --- /dev/null +++ b/expcore/async.lua @@ -0,0 +1,71 @@ +--[[-- Core Module - Async + - An extention of task and token to allow a single require to register and run async functions. + @core Async + @alias Async + + @usage + -- To use Async you must register the allowed functions when the files are loaded, often this will just be giving access to + -- some functions within a module if you expect that some parts may be blocked by in game permissions or a custom system you have made + -- you may also want to register functions that you want to have a delayed call, such as waiting 2 seconds before printing a message + + -- This player.admin is called (command or gui element event) by a player who isnt admin then it will error + -- here we register the function to promote the player so that it will run async + local promote_player = + Async.register(function(player) + player.admin = true + end) + + -- This will allow us to bypass this by running one tick later outside of any player scope + Async(promote_player,game.player) + + -- Here we make an sync function that we want to have a delay, note the delay is not defined here + local print_message = + Async.register(function(player,message) + player.print(message) + end) + + -- We can then call the async function with a delay using the wait function + Async.wait(60,print_message,game.player,'One second has passed!') + +]] +local Task = require 'utils.task' --- @dep utils.task +local Token = require 'utils.token' --- @dep utils.token + +local Async = {} + +local internal_run = +Token.register(function(params) + local func = Token.get(params.token) + func(unpack(params.params)) +end) + +--- Register a new async function, must called when the file is loaded +-- @tparam function callback the function that will become an async function +Async.register = Token.register + +--- Runs the async function linked to this token, you may supply any number of params as needed +-- @tparam string token the token of the async function you want to run +-- @tparam[opt] any ... the other params that you want to pass to your function +function Async.run(token,...) + Task.queue_task(internal_run, { + token = token, + params = {...} + }) +end + +--- Runs the async function linked to this token after the given number of ticks, you may supply any number of params as needed +-- @tparam number ticks the number of ticks that you want the function to run after +-- @tparam string token the token of the async function you want to run +-- @tparam[opt] any ... the other params that you want to pass to your function +function Async.wait(ticks,token,...) + Task.set_timeout_in_ticks(ticks, internal_run, { + token = token, + params = {...} + }) +end + +return setmetatable(Async,{ + __call = function(self,...) + self.run(...) + end +}) \ No newline at end of file diff --git a/expcore/permission_groups.lua b/expcore/permission_groups.lua index 4fb10c05..136717e0 100644 --- a/expcore/permission_groups.lua +++ b/expcore/permission_groups.lua @@ -30,13 +30,27 @@ local Game = require 'utils.game' --- @dep utils.game local Event = require 'utils.event' --- @dep utils.event -local Sudo = require 'expcore.sudo' --- @dep expcore.sudo +local Async = require 'expcore.async' --- @dep expcore.async local Permissions_Groups = { groups={}, -- store for the different groups that are created _prototype={} -- stores functions that are used on group instances } +-- Async function to add players to permission groups +local add_to_permission_group = +Async.register(function(permission_group,player) + permission_group.add_player(player) +end) +Permissions_Groups.async_token_add_to_permission_group = add_to_permission_group + +-- Async function to remove players from permission groups +local remove_from_permission_group = +Async.register(function(permission_group,player) + permission_group.remove_player(player) +end) +Permissions_Groups.async_token_remove_from_permission_group = remove_from_permission_group + --- Getters. -- Functions that get permission groups -- @section getters @@ -224,7 +238,7 @@ function Permissions_Groups._prototype:add_player(player) player = Game.get_player_from_any(player) local group = self:get_raw() if not group or not player then return false end - Sudo('add-player-to-permission-group',group,player) + Async(add_to_permission_group, group, player) return true end @@ -235,7 +249,7 @@ function Permissions_Groups._prototype:remove_player(player) player = Game.get_player_from_any(player) local group = self:get_raw() if not group or not player then return false end - Sudo('remove-player-from-permission-group',group,player) + Async(remove_from_permission_group, group, player) return true end @@ -275,11 +289,4 @@ Event.on_init(function() Permissions_Groups.reload_permissions() end) -Sudo.register('add-player-to-permission-group',function(permission_group,player) - permission_group.add_player(player) -end) -Sudo.register('remove-player-from-permission-group',function(permission_group,player) - permission_group.remove_player(player) -end) - return Permissions_Groups \ No newline at end of file diff --git a/expcore/roles.lua b/expcore/roles.lua index e6b6e956..a9d68404 100644 --- a/expcore/roles.lua +++ b/expcore/roles.lua @@ -116,7 +116,7 @@ local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global local Event = require 'utils.event' --- @dep utils.event local Groups = require 'expcore.permission_groups' --- @dep expcore.permission_groups -local Sudo = require 'expcore.sudo' --- @dep expcore.sudo +local Async = require 'expcore.async' --- @dep expcore.async local Colours = require 'resources.color_presets' --- @dep resources.color_presets local write_json = ext_require('expcore.common','write_json') --- @dep expcore.common @@ -443,9 +443,7 @@ end -- flag param - player - the player that has had they roles changed -- flag param - state - the state of the flag, aka if the flag is present function Roles.define_flag_trigger(name,callback) - local sudo_name = 'role-flag-'..name - Roles.config.flags[name] = sudo_name - Sudo.register(sudo_name,callback) + Roles.config.flags[name] = Async.register(callback) end --- Sets the default role which every player will have, this needs to be called at least once @@ -748,9 +746,9 @@ end local function role_update(event) local player = Game.get_player_by_index(event.player_index) -- Updates flags given to the player - for flag,sudo_name in pairs(Roles.config.flags) do + for flag, async_token in pairs(Roles.config.flags) do local state = Roles.player_has_flag(player,flag) - Sudo(sudo_name,player,state) + Async(async_token, player, state) end -- Updates the players permission group local highest = Roles.get_player_highest_role(player) @@ -758,10 +756,10 @@ local function role_update(event) if highest.permission_group[1] then local group = game.permissions.get_group(highest.permission_group[2]) if group then - Sudo('add-player-to-permission-group',group,player) + Async(Groups.async_token_add_to_permission_group, group, player) end else - Groups.set_player_group(player,highest.permission_group) + Groups.set_player_group(player, highest.permission_group) end end end diff --git a/expcore/sudo.lua b/expcore/sudo.lua deleted file mode 100644 index 630e50af..00000000 --- a/expcore/sudo.lua +++ /dev/null @@ -1,76 +0,0 @@ ---[[-- Core Module - Sudo - - An extention of task and token to allow a single require to register and run functions bypassing all permissions. - @core Sudo - @alias Sudo - - @usage - -- To use sudo you must register the allowed functions when the files are loaded, often this will just be giving access to - -- some functions within a module if you expect that some parts may be blocked by in game permissions or a custom system you have made - - -- This will be blocked if the current player (from a command or gui) is not admin - local function make_admin(player) - player.admin = true - end - - -- Here we give sudo access to the function under the name "make-admin" - Sudo.register('make-admin',make_admin) - - -- This will allow us to bypass this by running one tick later outside of any player scope - Sudo.run('make-admin',game.player) -]] -local Task = require 'utils.task' --- @dep utils.task -local Token = require 'utils.token' --- @dep utils.token - -local Sudo = { - tokens={} -} - -local internal_run = -Token.register(function(params) - local func = Token.get(params.token) - func(unpack(params.params)) -end) - ---- Registers a new callback under the given name, used to avoid desyncs --- @tparam string name the name that will be used to call this function --- @tparam function callback the function that will be called by this name -function Sudo.register(name,callback) - if _LIFECYCLE == 8 then - error('Calling Sudo.register after on_init() or on_load() has run is a desync risk.', 2) - end - - if Sudo.tokens[name] then - error(name..' is already registered',2) - end - - Sudo.tokens[name] = Token.register(callback) -end - ---- Gets the function that is registered under the given name --- @tparam string name the name of the function you want to get -function Sudo.get(name) - local token = Sudo.tokens[name] - return token and Token.get(token) -end - ---- Runs the function that is registered under the given name, you may supply any number of params as needed --- @tparam string name the name of the function you want to run --- @tparam[opt] any ... the other params that you want to pass to your function -function Sudo.run(name,...) - local token = Sudo.tokens[name] - - if not token then - error('Sudo does not have access to run "'..tostring(name)..'" please make sure it is registered to sudo',2) - end - - Task.set_timeout_in_ticks(1, internal_run, { - token = token, - params = {...} - }) -end - -return setmetatable(Sudo,{ - __call = function(self,...) - self.run(...) - end -}) \ No newline at end of file diff --git a/modules/commands/interface.lua b/modules/commands/interface.lua index 51b20ebf..67dbd035 100644 --- a/modules/commands/interface.lua +++ b/modules/commands/interface.lua @@ -17,7 +17,7 @@ local interface_modules = { ['Roles']='expcore.roles', ['Store']='expcore.store', ['Gui']='expcore.gui', - ['Sudo']='expcore.sudo' + ['Async']='expcore.async' } -- loads all the modules given in the above table From da4b14588a01ee3cd7c4efc160f8ef6496499420 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 18 Feb 2020 19:10:03 +0000 Subject: [PATCH 25/81] Added math.floor --- modules/addons/advanced-start.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/addons/advanced-start.lua b/modules/addons/advanced-start.lua index fea02aea..3e93c853 100644 --- a/modules/addons/advanced-start.lua +++ b/modules/addons/advanced-start.lua @@ -22,6 +22,7 @@ Event.add(defines.events.on_player_created, function(event) local stats = player.force.item_production_statistics local made = stats.get_input_count(item) local success,count = pcall(callback,made,stats.get_input_count,player) + count = math.floor(count) if success and count > 0 then player.insert{name=item,count=count} end From b102bdbc7fa08111c8bc1826ee11b56dbf404311 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 18 Feb 2020 19:17:53 +0000 Subject: [PATCH 26/81] Disabled pattern matching --- modules/addons/chat-popups.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/addons/chat-popups.lua b/modules/addons/chat-popups.lua index 814478a5..1ff2b107 100644 --- a/modules/addons/chat-popups.lua +++ b/modules/addons/chat-popups.lua @@ -28,7 +28,7 @@ Event.add(defines.events.on_console_chat,function(event) -- Loops over online players to see if they name is included for _,mentioned_player in pairs(game.connected_players) do if mentioned_player.index ~= player.index then - if search_string:match(mentioned_player.name:lower()) then + if search_string:match(mentioned_player.name:lower(), 1, true) then send_text(mentioned_player.index,{'chat-popup.ping',player.name},player.chat_color) end end From 105f53f629ee16598d34c60f4317e6b839bb4fd9 Mon Sep 17 00:00:00 2001 From: badgamernl Date: Fri, 21 Feb 2020 23:21:06 +0100 Subject: [PATCH 27/81] Fixed warp button init --- modules/gui/warp-list.lua | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index e51e01c3..66626780 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -436,16 +436,7 @@ end) --- Button on the top flow used to toggle the warp list container -- @element warp_list_toggle -Gui.element{ - type = 'sprite-button', - sprite = 'item/'..config.default_icon, - tooltip = {'warp-list.main-tooltip',config.standard_proximity_radius}, - style = Gui.top_flow_button_style -} -:style{ - padding = -2 -} -:add_to_top_flow(function(player) +Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',config.standard_proximity_radius},warp_list_container, function(player) return Roles.player_allowed(player,'gui/warp-list') end) :on_click(function(player,_,_) From bcde7943add47ffea8c0894b5b6e462f238282c0 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 23 Feb 2020 23:39:09 +0000 Subject: [PATCH 28/81] Split gui core into multiple files --- expcore/gui.lua | 920 +------------------------------ expcore/gui/core_defines.lua | 87 +++ expcore/gui/defines.lua | 218 ++++++++ expcore/gui/helper_functions.lua | 91 +++ expcore/gui/left_flow.lua | 180 ++++++ expcore/gui/prototype.lua | 352 ++++++++++++ expcore/gui/require.lua | 8 + expcore/gui/top_flow.lua | 99 ++++ 8 files changed, 1036 insertions(+), 919 deletions(-) create mode 100644 expcore/gui/core_defines.lua create mode 100644 expcore/gui/defines.lua create mode 100644 expcore/gui/helper_functions.lua create mode 100644 expcore/gui/left_flow.lua create mode 100644 expcore/gui/prototype.lua create mode 100644 expcore/gui/require.lua create mode 100644 expcore/gui/top_flow.lua diff --git a/expcore/gui.lua b/expcore/gui.lua index de0cd8f9..eaa22047 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -1,919 +1 @@ ---[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers -@core Gui -@alias Gui - -@usage-- Defining a button that prints the player's name -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:on_click(function(player,element,event) - player.print(player.name) -end) - -@usage-- Defining a button with a custom style -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:style{ - height = 25, - width = 100 -} -:on_click(function(player,element,event) - player.print(player.name) -end) - -@usage-- Defining a button using a custom function -local example_flow_with_button = -Gui.element(function(event_trigger,parent) - -- Add the flow the button is in - local flow = - parent.add{ - name = 'example_flow', - type = 'flow' - } - - -- Get the players name - local player = game.players[parent.player_index] - local player_name = player.name - - -- Add the button - local element = - flow.add{ - name = event_trigger, - type = 'button', - caption = 'Example Button: '..player_name - } - - -- Set the style of the button - local style = element.style - style.height = 25 - style.width = 100] - style.font_color = player.color - - -- Return the element - return element -end) -:on_click(function(player,element,event) - player.print(player.name) -end) - -@usage-- Drawing an element -local exmple_button_element = example_button(parent) -local example_flow_with_button = example_flow_with_button(parent) - -]] - -local Event = require 'utils.event' --- @dep utils.event -local mod_gui = require 'mod-gui' --- @dep mod-gui - -local Gui = { - --- The current highest uid that is being used, will not increase during runtime - -- @field uid - uid = 0, - --- Contains the uids of the elements that will show on the top flow and the auth function - -- @table top_elements - top_elements = {}, - --- Contains the uids of the elements that will show on the left flow and the open on join function - -- @table left_elements - left_elements = {}, - --- Table of all the elements which have been registed with the draw function and event handlers - -- @table defines - defines = {}, - --- An index used for debuging to find the file where different elements where registered - -- @table file_paths - file_paths = {}, - --- An index used for debuging to show the raw data used to define an element - -- @table debug_info - debug_info = {}, - --- The element prototype which is returned from Gui.element - -- @table _prototype_element - _prototype_element = {}, - --- The prototype metatable applied to new element defines - -- @table _mt_element - _mt_element = { - __call = function(self,parent,...) - local element = self._draw(self.name,parent,...) - if self._style then self._style(element.style,element,...) end - return element - end - } -} - -Gui._mt_element.__index = Gui._prototype_element - ---- Element Define. --- @section elementDefine - ---[[-- Base function used to define new elements, can be used with a table or with a function -@tparam ?table|function element_define used to define how the element is draw, using a table is the simplist way of doing this -@treturn table the new element define that is used to register events to this element - -@usage-- Defining an element with a table -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} - -@usage-- Defining an element with a function -local example_flow_with_button = -Gui.element(function(event_trigger,parent,...) - -- Add the flow the button is in - local flow = - parent.add{ - name = 'example_flow', - type = 'flow' - } - - -- Add the button - local element = - flow.add{ - name = event_trigger, - type = 'button', - caption = 'Example Button' - } - - -- Set the style of the button - local style = element.style - style.height = 25 - style.width = 100 - - -- Return the element - return element -end) - -]] -function Gui.element(element_define) - -- Set the metatable to allow access to register events - local element = setmetatable({}, Gui._mt_element) - - -- Increment the uid counter - local uid = Gui.uid + 1 - Gui.uid = uid - local name = tostring(uid) - element.name = name - Gui.debug_info[name] = { draw = 'None', style = 'None', events = {} } - - -- Add the defination function - if type(element_define) == 'table' then - Gui.debug_info[name].draw = element_define - element_define.name = name - element._draw = function(_,parent) - return parent.add(element_define) - end - else - Gui.debug_info[name].draw = 'Function' - element._draw = element_define - end - - -- Add the define to the base module - local file_path = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) - Gui.file_paths[name] = file_path - Gui.defines[name] = element - - -- Return the element so event handers can be accessed - return element -end - ---[[-- Extension of Gui.element when using the table method, values applied after the element is drawn -@tparam ?table|function style_define used to define how the style is applied, using a table is the simplist way of doing this -@treturn table the new element define that is used to register events to this element - -@usage-- Setting the height and width of the example button -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:style{ - height = 25, - width = 100 -} - -@usage-- Using a function to set the style -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:style(function(style,element,...) - local player = game.players[element.player_index] - style.height = 25 - style.width = 100 - style.font_color = player.color -end) - -]] -function Gui._prototype_element:style(style_define) - -- Add the defination function - if type(style_define) == 'table' then - Gui.debug_info[self.name].style = style_define - self._style = function(style) - for key,value in pairs(style_define) do - style[key] = value - end - end - else - Gui.debug_info[self.name].style = 'Function' - self._style = style_define - end - - -- Return the element so event handers can be accessed - return self -end - ---[[-- Adds an element to be drawn to the top flow when a player joins -@tparam[opt] function authenticator called during toggle or update to decide if the element should be visible -@treturn table the new element define that is used to register events to this element - -@usage-- Adding the example button -example_button:add_to_top_flow(function(player) - -- example button will only show when game time is less than 1 minute - return player.online_time < 3600 -end) - -]] -function Gui._prototype_element:add_to_top_flow(authenticator) - Gui.top_elements[self.name] = authenticator or true - return self -end - ---[[-- Adds an element to be drawn to the left flow when a player joins -@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible -@treturn table the new element define that is used to register events to this element - -@usage-- Adding the example button -example_flow_with_button:add_to_left_flow(true) - -]] -function Gui._prototype_element:add_to_left_flow(open_on_join) - Gui.left_elements[self.name] = open_on_join or false - return self -end - --- This function is called for event event -local function general_event_handler(event) - -- Check the element is valid - local element = event.element - if not element or not element.valid then - return - end - - -- Get the event handler for this element - local handlers = Gui.defines[element.name] - local handler = handlers and handlers[event.name] - if not handler then - return - end - - -- Get the player for this event - local player = game.players[event.player_index] - if not player or not player.valid then - return - end - event.player = player - - local success, err = pcall(handler,player,element,event) - if not success then - error('There as been an error with an event handler for a gui element:\n\t'..err) - end -end - --- This function returns the event handler adder and registeres the general handler -local function event_handler_factory(event_name) - Event.add(event_name, general_event_handler) - - return function(self,handler) - table.insert(Gui.debug_info[self.name].events,debug.getinfo(1, "n").name) - self[event_name] = handler - return self - end -end - ---- Element Events. --- @section elementEvents - ---- Called when the player opens a GUI. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_opened = event_handler_factory(defines.events.on_gui_opened) - ---- Called when the player closes the GUI they have open. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_closed = event_handler_factory(defines.events.on_gui_closed) - ---- Called when LuaGuiElement is clicked. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click) - ---- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed) - ---- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed) - ---- Called when LuaGuiElement element value is changed (related to choose element buttons). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed) - ---- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed) - ---- Called when LuaGuiElement selected tab is changed (related to tabbed-panes). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed) - ---- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed) - ---- Called when LuaGuiElement switch state is changed (related to switches). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed) - ---- Called when LuaGuiElement text is changed by the player. --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed) - ---- Called when LuaGuiElement slider value is changed (related to the slider element). --- @tparam function handler the event handler which will be called -Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) - ---- Top Flow. --- @section topFlow - ---- The style that should be used for buttons on the top flow --- @field Gui.top_flow_button_style -Gui.top_flow_button_style = mod_gui.button_style - ---[[-- Gets the flow which contains the elements for the top flow -@function Gui.get_top_flow(player) -@tparam LuaPlayer player the player that you want to get the flow for -@treturn LuaGuiElement the top element flow - -@usage-- Geting your top element flow -local top_flow = Gui.get_top_flow(game.player) - -]] -Gui.get_top_flow = mod_gui.get_button_flow - ---- Button which toggles the top flow elements, shows inside top flow --- @element hide_top_flow -local hide_top_flow = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/preset', - style = 'tool_button', - tooltip = {'gui_util.button_tooltip'} -} -:style{ - padding = -2, - width = 18, - height = 36 -} -:on_click(function(player,_,_) - Gui.toggle_top_flow(player) -end) - ---- Button which toggles the top flow elements, shows inside left flow --- @element show_top_flow -local show_top_flow = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/preset', - style = 'tool_button', - tooltip = {'gui_util.button_tooltip'} -} -:style{ - padding = -2, - width = 18, - height = 20 -} -:on_click(function(player,_,_) - Gui.toggle_top_flow(player) -end) - ---[[-- Updates the visible states of all the elements on a players top flow -@tparam LuaPlayer player the player that you want to update the flow for - -@usage-- Update your flow -Gui.update_top_flow(game.player) - -]] -function Gui.update_top_flow(player) - local top_flow = Gui.get_top_flow(player) - local hide_button = top_flow[hide_top_flow.name] - local is_visible = hide_button.visible - - -- Set the visible state of all elements in the flow - for name,authenticator in pairs(Gui.top_elements) do - -- Ensure the element exists - local element = top_flow[name] - if not element then - element = Gui.defines[name](top_flow) - end - - -- Set the visible state - element.visible = is_visible and authenticator(player) or false - end -end - ---[[-- Toggles the visible states of all the elements on a players top flow -@tparam LuaPlayer player the player that you want to toggle the flow for -@tparam[opt] boolean state if given then the state will be set to this state -@treturn boolean the new visible state of the top flow - -@usage-- Toggle your flow -Gui.toggle_top_flow(game.player) - -@usage-- Open your top flow -Gui.toggle_top_flow(game.player,true) - -]] -function Gui.toggle_top_flow(player,state) - -- Get the top flow and hide button - local top_flow = Gui.get_top_flow(player) - if state == nil then state = not top_flow.visible end - - -- Change the visiblty of the flow - local left_flow = Gui.get_left_flow(player) - local show_button = left_flow.gui_core_buttons[show_top_flow.name] - show_button.visible = not state - top_flow.visible = state - - return state -end - ---- Left Flow. --- @section leftFlow - ---[[-- Gets the flow which contains the elements for the left flow -@function Gui.get_left_flow(player) -@tparam LuaPlayer player the player that you want to get the flow for -@treturn LuaGuiElement the left element flow - -@usage-- Geting your left element flow -local left_flow = Gui.get_left_flow(game.player) - -]] -Gui.get_left_flow = mod_gui.get_frame_flow - ---- Button which hides the elements in the left flow --- @element hide_left_flow -local hide_left_flow = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/close_black', - style = 'tool_button', - tooltip = {'expcore-gui.left-button-tooltip'} -} -:style{ - padding = -3, - width = 18, - height = 20 -} -:on_click(function(player,_,_) - Gui.hide_left_flow(player) -end) - ---[[-- Button which can be used to toggle a left element, placed on the top flow -@tparam string sprite the sprite that you want to use on the button -@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have -@tparam table element_define the element define that you want to be toggled on the left flow -@tparam[opt] function authenticator used to decide if the button should be visible to a player - -@usage-- Add a button to toggle a left element -local toolbar_button = Gui.left_toolbar_button('entity/inserter','Nothing to see here',example_flow_with_button,function(player) - return player.admin -end) - -]] -function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) - return Gui.element{ - type = 'sprite-button', - sprite = sprite, - tooltip = tooltip, - style = Gui.top_flow_button_style - } - :style{ - padding = -2 - } - :add_to_top_flow(authenticator) - :on_click(function(player,_,_) - Gui.toggle_left_element(player, element_define) - end) -end - ---[[-- Hides all left elements for a player -@tparam LuaPlayer player the player to hide the elements for - -@usage-- Hide your left elements -Gui.hide_left_flow(game.player) - -]] -function Gui.hide_left_flow(player) - local left_flow = Gui.get_left_flow(player) - local hide_button = left_flow.gui_core_buttons[hide_left_flow.name] - - -- Set the visible state of all elements in the flow - hide_button.visible = false - for name,_ in pairs(Gui.left_elements) do - left_flow[name].visible = false - end -end - ---[[-- Get the element define that is in the left flow -@tparam LuaPlayer player the player that you want tog et the element for -@tparam table element_define the element that you want to get for the player -@treturn LuaGuiElement the gui element linked to this define in the left flow - -@usage-- Get your left element -local frame = Gui.get_left_element(game.player,example_flow_with_button) - -]] -function Gui.get_left_element(player,element_define) - local left_flow = Gui.get_left_flow(player) - return left_flow[element_define.name] -end - ---[[-- Toggles the visible state of a left element for a player -@tparam LuaPlayer player the player that you want to toggle the element for -@tparam table element_define the element that you want to toggle for the player -@tparam[opt] boolean state if given then the state will be set to this state -@treturn boolean the new visible state of the element - -@usage-- Toggle your example button -Gui.toggle_top_flow(game.player,example_flow_with_button) - -@usage-- Open your example button -Gui.toggle_top_flow(game.player,example_flow_with_button,true) - -]] -function Gui.toggle_left_element(player,element_define,state) - local left_flow = Gui.get_left_flow(player) - local hide_button = left_flow.gui_core_buttons[hide_left_flow.name] - - -- Set the visible state - local element = left_flow[element_define.name] - if state == nil then state = not element.visible end - element.visible = state - - -- Check if the hide button should be visible - local show_hide_button = false - for name,_ in pairs(Gui.left_elements) do - if left_flow[name].visible then - show_hide_button = true - break - end - end - hide_button.visible = show_hide_button - - return state -end - --- Draw the two flows when a player joins -Event.add(defines.events.on_player_created,function(event) - local player = game.players[event.player_index] - - -- Draw the top flow - local top_flow = Gui.get_top_flow(player) - hide_top_flow(top_flow) - Gui.update_top_flow(player) - - -- Draw the left flow - local left_flow = Gui.get_left_flow(player) - local button_flow = left_flow.add{ type = 'flow', name = 'gui_core_buttons', direction = 'vertical' } - local show_top = show_top_flow(button_flow) - local hide_left = hide_left_flow(button_flow) - show_top.visible = false - - -- Draw the elements on the left flow - local show_hide_left = false - for name,open_on_join in pairs(Gui.left_elements) do - local left_element = Gui.defines[name](left_flow) - - -- Check if the element should be visible - local visible = type(open_on_join) == 'boolean' and open_on_join or false - if type(open_on_join) == 'function' then - local success, err = pcall(open_on_join, player) - if not success then - error('There as been an error with an open on join hander for a gui element:\n\t'..err) - end - visible = err - end - - left_element.visible = visible - if visible then - show_hide_left = true - end - end - - hide_left.visible = show_hide_left -end) - ---- Helper Functions. --- @section helperFunctions - ---[[-- Get the player that owns a gui element -@tparam LuaGuiElement element the element that you want to get the owner of -@treturn LuaPlayer the player that owns this element - -@usage-- Geting the owner of an element -local player = Gui.get_player_from_element(element) - -]] -function Gui.get_player_from_element(element) - if not element or not element.valid then return end - return game.players[element.player_index] -end - ---[[-- Will toggle the enabled state of an element or set it to the one given -@tparam LuaGuiElement element the element that you want to toggle the state of -@tparam[opt] boolean state the state that you want to set -@treturn boolean the new enabled state that the element has - -@usage-- Toggling the the enabled state -local new_enabled_state = Gui.toggle_enabled_state(element) - -]] -function Gui.toggle_enabled_state(element,state) - if not element or not element.valid then return end - if state == nil then state = not element.enabled end - element.enabled = state - return state -end - ---[[-- Will toggle the visible state of an element or set it to the one given -@tparam LuaGuiElement element the element that you want to toggle the state of -@tparam[opt] boolean state the state that you want to set -@treturn boolean the new visible state that the element has - -@usage-- Toggling the the visible state -local new_visible_state = Gui.toggle_visible_state(element) - -]] -function Gui.toggle_visible_state(element,state) - if not element or not element.valid then return end - if state == nil then state = not element.visible end - element.visible = state - return state -end - ---[[-- Destory a gui element without causing any errors, likly if the element may have already been removed -@tparam LuaGuiElement element the element that you want to remove -@treturn boolean true if the element was valid and has been removed - -@usage-- Likely use case for element not existing -Gui.destroy_if_valid(element[child_name]) - -]] -function Gui.destroy_if_valid(element) - if not element or not element.valid then return false end - element.destroy() - return true -end - ---[[-- Returns a table to be used as a style on sprite buttons, produces a sqaure button -@tparam number size the size that you want the button to be -@tparam[opt=-2] number padding the padding that you want on the sprite -@tparam[opt] table style any extra style settings that you want to have -@treturn table the style table to be used with element_define:style() - -@usage-- Adding a sprite button with size 20 -local button = -Gui.element{ - type = 'sprite-button', - sprite = 'entity/inserter' -} -:style(Gui.sprite_style(20)) - -]] -function Gui.sprite_style(size,padding,style) - style = style or {} - style.padding = padding or -2 - style.height = size - style.width = size - return style -end - ---[[-- Draw a flow that has custom element alignments, default is right align -@element Gui.alignment -@tparam LuaGuiElement parent the parent element that the alignment flow will be added to -@tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow -@tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow -@tparam[opt='alignment'] string name the name of the alignment flow -@treturn LuaGuiElement the alignment flow that was created - -@usage-- Adding a right align flow -local alignment = Gui.alignment(element,'example_right_alignment') - -@usage-- Adding a horizontal center and top align flow -local alignment = Gui.alignment(element,'example_center_top_alignment','center','top') - -]] -Gui.alignment = -Gui.element(function(_,parent,_,_,name) - return parent.add{ - name = name or 'alignment', - type = 'flow', - } -end) -:style(function(style,_,horizontal_align,vertical_align,_) - style.padding = {1,2} - style.vertical_align = vertical_align or 'center' - style.horizontal_align = horizontal_align or 'right' - style.vertically_stretchable = style.vertical_align ~= 'center' - style.horizontally_stretchable = style.horizontal_align ~= 'center' -end) - ---[[-- Draw a scroll pane that has a table inside of it -@element Gui.scroll_table -@tparam LuaGuiElement parent the parent element that the scroll table will be added to -@tparam number height the maximum height for the scroll pane -@tparam number column_count the number of columns that the table will have -@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called 'table' -@treturn LuaGuiElement the table that was created - -@usage-- Adding a scroll table with max height of 200 and column count of 3 -local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) - -]] -Gui.scroll_table = -Gui.element(function(_,parent,_,column_count,name) - -- Draw the scroll - local scroll_pane = - parent.add{ - name = name or 'scroll', - type = 'scroll-pane', - direction = 'vertical', - horizontal_scroll_policy = 'never', - vertical_scroll_policy = 'auto', - style = 'scroll_pane_under_subheader' - } - - -- Draw the table - local scroll_table = - scroll_pane.add{ - type = 'table', - name = 'table', - column_count = column_count - } - - -- Return the scroll table - return scroll_table -end) -:style(function(style,element,height,_,_) - -- Change the style of the scroll - local scroll_style = element.parent.style - scroll_style.padding = {1,3} - scroll_style.maximal_height = height - scroll_style.horizontally_stretchable = true - - -- Change the style of the table - style.padding = 0 - style.cell_padding = 0 - style.vertical_align = 'center' - style.horizontally_stretchable = true -end) - ---[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons -@element Gui.header -@tparam LuaGuiElement parent the parent element that the header will be added to -@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header -@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header -@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons -@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' -@treturn LuaGuiElement either the header or the header alignment if add_alignment is true - -@usage-- Adding a custom header with a label -local header_alignment = Gui.header( - element, - 'Example Caption', - 'Example Tooltip', - true -) - -]] -Gui.header = -Gui.element(function(_,parent,caption,tooltip,add_alignment,name) - -- Draw the header - local header = - parent.add{ - name = name or 'header', - type = 'frame', - style = 'subheader_frame' - } - - -- Change the style of the header - local style = header.style - style.padding = {2,4} - style.use_header_filler = false - style.horizontally_stretchable = true - - -- Draw the caption label - if caption then - header.add{ - name = 'header_label', - type = 'label', - style = 'heading_1_label', - caption = caption, - tooltip = tooltip - } - end - - -- Return either the header or the added alignment - return add_alignment and Gui.alignment(header) or header -end) - ---[[-- Used to add a footer to a frame, this has the option for a custom right alignment flow for buttons -@element Gui.header -@tparam LuaGuiElement parent the parent element that the footer will be added to -@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the footer -@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the footer -@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons -@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called 'alignment' -@treturn LuaGuiElement either the footer or the footer alignment if add_alignment is true - -@usage-- Adding a custom footer with a label -local header_alignment = Gui.footer( - element, - 'Example Caption', - 'Example Tooltip', - true -) - -]] -Gui.footer = -Gui.element(function(_,parent,caption,tooltip,add_alignment,name) - -- Draw the header - local footer = - parent.add{ - name = name or 'footer', - type = 'frame', - style = 'subfooter_frame' - } - - -- Change the style of the footer - local style = footer.style - style.padding = {2,4} - style.use_header_filler = false - style.horizontally_stretchable = true - - -- Draw the caption label - if caption then - footer.add{ - name = 'footer_label', - type = 'label', - style = 'heading_1_label', - caption = caption, - tooltip = tooltip - } - end - - -- Return either the footer or the added alignment - return add_alignment and Gui.alignment(footer) or footer -end) - ---[[-- Used for left frame to add a nice boarder to them and contain them -@element Gui.container -@tparam LuaGuiElement parent the parent element that the container will be added to -@tparam string name the name that you want to give the outer frame, often just event_trigger for a left frame -@tparam number width the minimal width that the frame will have - -@usage-- Adding a container as a base -local container = Gui.container(parent,'my_container',200) - -]] -Gui.container = -Gui.element(function(_,parent,name,_) - -- Draw the external container - local frame = - parent.add{ - name = name, - type = 'frame' - } - - -- Return the container - return frame.add{ - name = 'container', - type = 'frame', - direction = 'vertical', - style = 'window_content_frame_packed' - } -end) -:style(function(style,element,_,width) - style.vertically_stretchable = false - local frame_style = element.parent.style - frame_style.padding = 2 - frame_style.minimal_width = width -end) - --- Module return -return Gui \ No newline at end of file +return require 'expcore.gui.require' \ No newline at end of file diff --git a/expcore/gui/core_defines.lua b/expcore/gui/core_defines.lua new file mode 100644 index 00000000..5c26bea7 --- /dev/null +++ b/expcore/gui/core_defines.lua @@ -0,0 +1,87 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' +local Event = require 'utils.event' --- @dep utils.event + +--- Core Defines. +-- @section coreDefines + +--- Button which toggles the top flow elements, shows inside top flow +-- @element hide_top_flow +local hide_top_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/preset', + style = 'tool_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + padding = -2, + width = 18, + height = 36 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) +end) +Gui.core_defines.hide_top_flow = hide_top_flow + +--- Button which toggles the top flow elements, shows inside left flow +-- @element show_top_flow +local show_top_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/preset', + style = 'tool_button', + tooltip = {'gui_util.button_tooltip'} +} +:style{ + padding = -2, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.toggle_top_flow(player) +end) +Gui.core_defines.show_top_flow = show_top_flow + +--- Button which hides the elements in the left flow +-- @element hide_left_flow +local hide_left_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + style = 'tool_button', + tooltip = {'expcore-gui.left-button-tooltip'} +} +:style{ + padding = -3, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.hide_left_flow(player) +end) +Gui.core_defines.hide_left_flow = hide_left_flow + +--- Draw the core elements when a player joins the game +Event.add(defines.events.on_player_created,function(event) + local player = game.players[event.player_index] + + -- Draw the top flow + local top_flow = Gui.get_top_flow(player) + hide_top_flow(top_flow) + Gui.update_top_flow(player) + + -- Draw the left flow + local left_flow = Gui.get_left_flow(player) + local button_flow = left_flow.add{ type = 'flow', name = 'gui_core_buttons', direction = 'vertical' } + local show_top = show_top_flow(button_flow) + local hide_left = hide_left_flow(button_flow) + show_top.visible = false + hide_left.visible = false + Gui.draw_left_flow(player) + +end) \ No newline at end of file diff --git a/expcore/gui/defines.lua b/expcore/gui/defines.lua new file mode 100644 index 00000000..db52d8ca --- /dev/null +++ b/expcore/gui/defines.lua @@ -0,0 +1,218 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' + +--[[-- Draw a flow that has custom element alignments, default is right align +@element Gui.alignment +@tparam LuaGuiElement parent the parent element that the alignment flow will be added to +@tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow +@tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow +@tparam[opt='alignment'] string name the name of the alignment flow +@treturn LuaGuiElement the alignment flow that was created + +@usage-- Adding a right align flow +local alignment = Gui.alignment(element,'example_right_alignment') + +@usage-- Adding a horizontal center and top align flow +local alignment = Gui.alignment(element,'example_center_top_alignment','center','top') + +]] +Gui.alignment = +Gui.element(function(_,parent,_,_,name) + return parent.add{ + name = name or 'alignment', + type = 'flow', + } +end) +:style(function(style,_,horizontal_align,vertical_align,_) + style.padding = {1,2} + style.vertical_align = vertical_align or 'center' + style.horizontal_align = horizontal_align or 'right' + style.vertically_stretchable = style.vertical_align ~= 'center' + style.horizontally_stretchable = style.horizontal_align ~= 'center' +end) + +--[[-- Draw a scroll pane that has a table inside of it +@element Gui.scroll_table +@tparam LuaGuiElement parent the parent element that the scroll table will be added to +@tparam number height the maximum height for the scroll pane +@tparam number column_count the number of columns that the table will have +@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called 'table' +@treturn LuaGuiElement the table that was created + +@usage-- Adding a scroll table with max height of 200 and column count of 3 +local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) + +]] +Gui.scroll_table = +Gui.element(function(_,parent,_,column_count,name) + -- Draw the scroll + local scroll_pane = + parent.add{ + name = name or 'scroll', + type = 'scroll-pane', + direction = 'vertical', + horizontal_scroll_policy = 'never', + vertical_scroll_policy = 'auto', + style = 'scroll_pane_under_subheader' + } + + -- Draw the table + local scroll_table = + scroll_pane.add{ + type = 'table', + name = 'table', + column_count = column_count + } + + -- Return the scroll table + return scroll_table +end) +:style(function(style,element,height,_,_) + -- Change the style of the scroll + local scroll_style = element.parent.style + scroll_style.padding = {1,3} + scroll_style.maximal_height = height + scroll_style.horizontally_stretchable = true + + -- Change the style of the table + style.padding = 0 + style.cell_padding = 0 + style.vertical_align = 'center' + style.horizontally_stretchable = true +end) + +--[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons +@element Gui.header +@tparam LuaGuiElement parent the parent element that the header will be added to +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons +@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' +@treturn LuaGuiElement either the header or the header alignment if add_alignment is true + +@usage-- Adding a custom header with a label +local header_alignment = Gui.header( + element, + 'Example Caption', + 'Example Tooltip', + true +) + +]] +Gui.header = +Gui.element(function(_,parent,caption,tooltip,add_alignment,name) + -- Draw the header + local header = + parent.add{ + name = name or 'header', + type = 'frame', + style = 'subheader_frame' + } + + -- Change the style of the header + local style = header.style + style.padding = {2,4} + style.use_header_filler = false + style.horizontally_stretchable = true + + -- Draw the caption label + if caption then + header.add{ + name = 'header_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + end + + -- Return either the header or the added alignment + return add_alignment and Gui.alignment(header) or header +end) + +--[[-- Used to add a footer to a frame, this has the option for a custom right alignment flow for buttons +@element Gui.header +@tparam LuaGuiElement parent the parent element that the footer will be added to +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the footer +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the footer +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons +@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called 'alignment' +@treturn LuaGuiElement either the footer or the footer alignment if add_alignment is true + +@usage-- Adding a custom footer with a label +local header_alignment = Gui.footer( + element, + 'Example Caption', + 'Example Tooltip', + true +) + +]] +Gui.footer = +Gui.element(function(_,parent,caption,tooltip,add_alignment,name) + -- Draw the header + local footer = + parent.add{ + name = name or 'footer', + type = 'frame', + style = 'subfooter_frame' + } + + -- Change the style of the footer + local style = footer.style + style.padding = {2,4} + style.use_header_filler = false + style.horizontally_stretchable = true + + -- Draw the caption label + if caption then + footer.add{ + name = 'footer_label', + type = 'label', + style = 'heading_1_label', + caption = caption, + tooltip = tooltip + } + end + + -- Return either the footer or the added alignment + return add_alignment and Gui.alignment(footer) or footer +end) + +--[[-- Used for left frame to add a nice boarder to them and contain them +@element Gui.container +@tparam LuaGuiElement parent the parent element that the container will be added to +@tparam string name the name that you want to give the outer frame, often just event_trigger for a left frame +@tparam number width the minimal width that the frame will have + +@usage-- Adding a container as a base +local container = Gui.container(parent,'my_container',200) + +]] +Gui.container = +Gui.element(function(_,parent,name,_) + -- Draw the external container + local frame = + parent.add{ + name = name, + type = 'frame' + } + + -- Return the container + return frame.add{ + name = 'container', + type = 'frame', + direction = 'vertical', + style = 'window_content_frame_packed' + } +end) +:style(function(style,element,_,width) + style.vertically_stretchable = false + local frame_style = element.parent.style + frame_style.padding = 2 + frame_style.minimal_width = width +end) \ No newline at end of file diff --git a/expcore/gui/helper_functions.lua b/expcore/gui/helper_functions.lua new file mode 100644 index 00000000..22106718 --- /dev/null +++ b/expcore/gui/helper_functions.lua @@ -0,0 +1,91 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' + +--- Helper Functions. +-- @section helperFunctions + +--[[-- Get the player that owns a gui element +@tparam LuaGuiElement element the element that you want to get the owner of +@treturn LuaPlayer the player that owns this element + +@usage-- Geting the owner of an element +local player = Gui.get_player_from_element(element) + +]] +function Gui.get_player_from_element(element) + if not element or not element.valid then return end + return game.players[element.player_index] +end + +--[[-- Will toggle the enabled state of an element or set it to the one given +@tparam LuaGuiElement element the element that you want to toggle the state of +@tparam[opt] boolean state the state that you want to set +@treturn boolean the new enabled state that the element has + +@usage-- Toggling the the enabled state +local new_enabled_state = Gui.toggle_enabled_state(element) + +]] +function Gui.toggle_enabled_state(element,state) + if not element or not element.valid then return end + if state == nil then state = not element.enabled end + element.enabled = state + return state +end + +--[[-- Will toggle the visible state of an element or set it to the one given +@tparam LuaGuiElement element the element that you want to toggle the state of +@tparam[opt] boolean state the state that you want to set +@treturn boolean the new visible state that the element has + +@usage-- Toggling the the visible state +local new_visible_state = Gui.toggle_visible_state(element) + +]] +function Gui.toggle_visible_state(element,state) + if not element or not element.valid then return end + if state == nil then state = not element.visible end + element.visible = state + return state +end + +--[[-- Destory a gui element without causing any errors, likly if the element may have already been removed +@tparam LuaGuiElement element the element that you want to remove +@treturn boolean true if the element was valid and has been removed + +@usage-- Likely use case for element not existing +Gui.destroy_if_valid(element[child_name]) + +]] +function Gui.destroy_if_valid(element) + if not element or not element.valid then return false end + element.destroy() + return true +end + +--[[-- Returns a table to be used as a style on sprite buttons, produces a sqaure button +@tparam number size the size that you want the button to be +@tparam[opt=-2] number padding the padding that you want on the sprite +@tparam[opt] table style any extra style settings that you want to have +@treturn table the style table to be used with element_define:style() + +@usage-- Adding a sprite button with size 20 +local button = +Gui.element{ + type = 'sprite-button', + sprite = 'entity/inserter' +} +:style(Gui.sprite_style(20)) + +]] +function Gui.sprite_style(size,padding,style) + style = style or {} + style.padding = padding or -2 + style.height = size + style.width = size + return style +end \ No newline at end of file diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua new file mode 100644 index 00000000..e21a10c1 --- /dev/null +++ b/expcore/gui/left_flow.lua @@ -0,0 +1,180 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' +local mod_gui = require 'mod-gui' --- @dep mod-gui + +local hide_left_flow = Gui.core_defines.hide_left_flow.name + +--- Left Flow. +-- @section leftFlow + +--- Contains the uids of the elements that will show on the left flow and the open on join function +-- @table left_elements +Gui.left_elements = {} + +--[[-- Gets the flow which contains the elements for the left flow +@function Gui.get_left_flow(player) +@tparam LuaPlayer player the player that you want to get the flow for +@treturn LuaGuiElement the left element flow + +@usage-- Geting your left element flow +local left_flow = Gui.get_left_flow(game.player) + +]] +Gui.get_left_flow = mod_gui.get_frame_flow + +--[[-- Adds an element to be drawn to the left flow when a player joins +@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible +@treturn table the new element define that is used to register events to this element + +@usage-- Adding the example button +example_flow_with_button:add_to_left_flow(true) + +]] +function Gui._prototype_element:add_to_left_flow(open_on_join) + Gui.left_elements[self.name] = open_on_join or false + return self +end + +--[[-- Button which can be used to toggle a left element, placed on the top flow +@tparam string sprite the sprite that you want to use on the button +@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have +@tparam table element_define the element define that you want to be toggled on the left flow +@tparam[opt] function authenticator used to decide if the button should be visible to a player + +@usage-- Add a button to toggle a left element +local toolbar_button = Gui.left_toolbar_button('entity/inserter','Nothing to see here',example_flow_with_button,function(player) + return player.admin +end) + +]] +function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) + return Gui.element{ + type = 'sprite-button', + sprite = sprite, + tooltip = tooltip, + style = Gui.top_flow_button_style + } + :style{ + padding = -2 + } + :add_to_top_flow(authenticator) + :on_click(function(player,_,_) + Gui.toggle_left_element(player, element_define) + end) +end + +--[[-- Draw all the left elements onto the left flow, internal use only +@tparam LuaPlayer player the player that you want to draw the elements for + +@usage Draw all the left elements +Gui.draw_left_flow(player) + +]] +function Gui.draw_left_flow(player) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow.gui_core_buttons[hide_left_flow] + local show_hide_button = false + + for name, open_on_join in pairs(Gui.left_elements) do + -- Draw the element to the left flow + local left_element = Gui.defines[name](left_flow) + + -- Check if it should be open by default + local visible = type(open_on_join) == 'boolean' and open_on_join or false + if type(open_on_join) == 'function' then + local success, err = pcall(open_on_join, player) + if not success then + error('There as been an error with an open on join hander for a gui element:\n\t'..err) + end + visible = err + end + + -- Set the visible state of the element + left_element.visible = visible + show_hide_button = show_hide_button or visible + end + + hide_button.visible = show_hide_button +end + +--[[-- Update the visible state of the hide left button, also draw left elements if not present +@tparam LuaPlayer player the player to update the left flow for +@treturn boolean true if any left element is visible + +@usage Check if any left elements are visible +local visible = Gui.update_left_flow(player) + +]] +function Gui.update_left_flow(player) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow.gui_core_buttons[hide_left_flow] + for name, _ in pairs(Gui.left_elements) do + local left_element = left_flow[name] + if left_element.visible then + hide_button.visible = true + return true + end + end + return false +end + +--[[-- Hides all left elements for a player +@tparam LuaPlayer player the player to hide the elements for + +@usage-- Hide your left elements +Gui.hide_left_flow(game.player) + +]] +function Gui.hide_left_flow(player) + local left_flow = Gui.get_left_flow(player) + local hide_button = left_flow.gui_core_buttons[hide_left_flow] + + -- Set the visible state of all elements in the flow + hide_button.visible = false + for name,_ in pairs(Gui.left_elements) do + left_flow[name].visible = false + end +end + +--[[-- Get the element define that is in the left flow +@tparam LuaPlayer player the player that you want tog et the element for +@tparam table element_define the element that you want to get for the player +@treturn LuaGuiElement the gui element linked to this define in the left flow + +@usage-- Get your left element +local frame = Gui.get_left_element(game.player,example_flow_with_button) + +]] +function Gui.get_left_element(player,element_define) + local left_flow = Gui.get_left_flow(player) + return left_flow[element_define.name] +end + +--[[-- Toggles the visible state of a left element for a player +@tparam LuaPlayer player the player that you want to toggle the element for +@tparam table element_define the element that you want to toggle for the player +@tparam[opt] boolean state if given then the state will be set to this state +@treturn boolean the new visible state of the element + +@usage-- Toggle your example button +Gui.toggle_top_flow(game.player,example_flow_with_button) + +@usage-- Open your example button +Gui.toggle_top_flow(game.player,example_flow_with_button,true) + +]] +function Gui.toggle_left_element(player,element_define,state) + local left_flow = Gui.get_left_flow(player) + + -- Set the visible state + local element = left_flow[element_define.name] + if state == nil then state = not element.visible end + element.visible = state + Gui.update_left_flow(player) + + return state +end \ No newline at end of file diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua new file mode 100644 index 00000000..75365bd1 --- /dev/null +++ b/expcore/gui/prototype.lua @@ -0,0 +1,352 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@core Gui +@alias Gui + +@usage-- Defining a button that prints the player's name +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:on_click(function(player,element,event) + player.print(player.name) +end) + +@usage-- Defining a button with a custom style +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style{ + height = 25, + width = 100 +} +:on_click(function(player,element,event) + player.print(player.name) +end) + +@usage-- Defining a button using a custom function +local example_flow_with_button = +Gui.element(function(event_trigger,parent) + -- Add the flow the button is in + local flow = + parent.add{ + name = 'example_flow', + type = 'flow' + } + + -- Get the players name + local player = game.players[parent.player_index] + local player_name = player.name + + -- Add the button + local element = + flow.add{ + name = event_trigger, + type = 'button', + caption = 'Example Button: '..player_name + } + + -- Set the style of the button + local style = element.style + style.height = 25 + style.width = 100] + style.font_color = player.color + + -- Return the element + return element +end) +:on_click(function(player,element,event) + player.print(player.name) +end) + +@usage-- Drawing an element +local exmple_button_element = example_button(parent) +local example_flow_with_button = example_flow_with_button(parent) + +]] + +local Event = require 'utils.event' --- @dep utils.event + +local Gui = { + --- The current highest uid that is being used, will not increase during runtime + -- @field uid + uid = 0, + --- An index of the element deinfes which are used by the core gui system + -- @table core_defines + core_defines = {}, + --- Table of all the elements which have been registed with the draw function and event handlers + -- @table defines + defines = {}, + --- Table of all custom events that are used by element defines, used to avoid conflicts + -- @table events + events = {}, + --- An index used for debuging to find the file where different elements where registered + -- @table file_paths + file_paths = {}, + --- An index used for debuging to show more data on element defines + -- @table debug_info + debug_info = {}, + --- The element prototype which is returned from Gui.element + -- @table _prototype_element + _prototype_element = {}, + --- The prototype metatable applied to new element defines + -- @table _mt_element + _mt_element = { + __call = function(self,parent,...) + local element = self._draw(self.name,parent,...) + if self._style then self._style(element.style,element,...) end + return element + end + } +} + +Gui._mt_element.__index = Gui._prototype_element + +--- Element Define. +-- @section elementDefine + +--[[-- Base function used to define new elements, can be used with a table or with a function +@tparam ?table|function element_define used to define how the element is draw, using a table is the simplist way of doing this +@treturn table the new element define that is used to register events to this element + +@usage-- Defining an element with a table +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} + +@usage-- Defining an element with a function +local example_flow_with_button = +Gui.element(function(event_trigger,parent,...) + -- Add the flow the button is in + local flow = + parent.add{ + name = 'example_flow', + type = 'flow' + } + + -- Add the button + local element = + flow.add{ + name = event_trigger, + type = 'button', + caption = 'Example Button' + } + + -- Set the style of the button + local style = element.style + style.height = 25 + style.width = 100 + + -- Return the element + return element +end) + +]] +function Gui.element(element_define) + -- Set the metatable to allow access to register events + local element = setmetatable({}, Gui._mt_element) + + -- Increment the uid counter + local uid = Gui.uid + 1 + Gui.uid = uid + local name = tostring(uid) + element.name = name + Gui.debug_info[name] = { draw = 'None', style = 'None', events = {} } + + -- Add the defination function + if type(element_define) == 'table' then + Gui.debug_info[name].draw = element_define + element_define.name = name + element._draw = function(_,parent) + return parent.add(element_define) + end + else + Gui.debug_info[name].draw = 'Function' + element._draw = element_define + end + + -- Add the define to the base module + local file_path = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) + Gui.file_paths[name] = file_path + Gui.defines[name] = element + + -- Return the element so event handers can be accessed + return element +end + +--[[-- Extension of Gui.element when using the table method, values applied after the element is drawn +@tparam ?table|function style_define used to define how the style is applied, using a table is the simplist way of doing this +@treturn table the new element define that is used to register events to this element + +@usage-- Setting the height and width of the example button +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style{ + height = 25, + width = 100 +} + +@usage-- Using a function to set the style +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:style(function(style,element,...) + local player = game.players[element.player_index] + style.height = 25 + style.width = 100 + style.font_color = player.color +end) + +]] +function Gui._prototype_element:style(style_define) + -- Add the defination function + if type(style_define) == 'table' then + Gui.debug_info[self.name].style = style_define + self._style = function(style) + for key,value in pairs(style_define) do + style[key] = value + end + end + else + Gui.debug_info[self.name].style = 'Function' + self._style = style_define + end + + -- Return the element so event handers can be accessed + return self +end + +--[[-- Set the handler to be called on a custom event, only one handler can be used +@tparam string event_name the name of the event you want to handler to be called on +@tparam function handler the handler that you want to be called when the event is raised +@treturn table the element define so more handleres can be registered + +@usage Print the player name when my_custom_event is raised +element_deinfe:on_custom_event('my_custom_event', function(event) + event.player.print(player.name) +end) + +]] +function Gui._prototype_element:on_custom_event(event_name,handler) + table.insert(Gui.debug_info[self.name].events,event_name) + Gui.events[event_name] = event_name + self[event_name] = handler + return self +end + +--[[-- Raise the handler which is attached to any event; external use should be limited to custom events +@tparam table event the event table bassed to the handler, must include fields: name, element + +@usage Raising a custom event +element_define:raise_custom_event{ + name = 'my_custom_event', + element = element +} + +]] +function Gui._prototype_element:raise_custom_event(event) + -- Check the element is valid + local element = event.element + if not element or not element.valid then + return + end + + -- Get the event handler for this element + local handler = self[event.name] + if not handler then + return + end + + -- Get the player for this event + local player_index = event.player_index or element.player_index + local player = game.players[player_index] + if not player or not player.valid then + return + end + event.player = player + + local success, err = pcall(handler,player,element,event) + if not success then + error('There as been an error with an event handler for a gui element:\n\t'..err) + end +end + +-- This function is used to register a link between element define events and the events in the factorio api +local function event_handler_factory(event_name) + Event.add(event_name, function(event) + local element = event.element + if not element or not element.valid then return end + local element_define = Gui.defines[element.name] + element_define:raise_custom_event(event) + end) + + return function(self,handler) + table.insert(Gui.debug_info[self.name].events,debug.getinfo(1, "n").name) + self[event_name] = handler + return self + end +end + +--- Element Events. +-- @section elementEvents + +--- Called when the player opens a GUI. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_opened = event_handler_factory(defines.events.on_gui_opened) + +--- Called when the player closes the GUI they have open. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_closed = event_handler_factory(defines.events.on_gui_closed) + +--- Called when LuaGuiElement is clicked. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click) + +--- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed) + +--- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed) + +--- Called when LuaGuiElement element value is changed (related to choose element buttons). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed) + +--- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed) + +--- Called when LuaGuiElement selected tab is changed (related to tabbed-panes). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed) + +--- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed) + +--- Called when LuaGuiElement switch state is changed (related to switches). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed) + +--- Called when LuaGuiElement text is changed by the player. +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed) + +--- Called when LuaGuiElement slider value is changed (related to the slider element). +-- @tparam function handler the event handler which will be called +Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) + +-- Module return +return Gui \ No newline at end of file diff --git a/expcore/gui/require.lua b/expcore/gui/require.lua new file mode 100644 index 00000000..26fcf0d6 --- /dev/null +++ b/expcore/gui/require.lua @@ -0,0 +1,8 @@ +local Gui = require 'expcore.gui.prototype' +require 'expcore.gui.core_defines' +require 'expcore.gui.top_flow' +require 'expcore.gui.left_flow' +require 'expcore.gui.helper_functions' +require 'expcore.gui.defines' + +return Gui \ No newline at end of file diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua new file mode 100644 index 00000000..b35eb2b0 --- /dev/null +++ b/expcore/gui/top_flow.lua @@ -0,0 +1,99 @@ +--[[-- Core Module - Gui +- Used to define new gui elements and gui event handlers +@module Gui +]] + +local Gui = require 'expcore.gui.prototype' +local mod_gui = require 'mod-gui' --- @dep mod-gui + +local hide_top_flow = Gui.core_defines.hide_top_flow.name +local show_top_flow = Gui.core_defines.show_top_flow.name + +--- Top Flow. +-- @section topFlow + +--- Contains the uids of the elements that will show on the top flow and the auth function +-- @table top_elements +Gui.top_elements = {} + +--- The style that should be used for buttons on the top flow +-- @field Gui.top_flow_button_style +Gui.top_flow_button_style = mod_gui.button_style + +--[[-- Gets the flow which contains the elements for the top flow +@function Gui.get_top_flow(player) +@tparam LuaPlayer player the player that you want to get the flow for +@treturn LuaGuiElement the top element flow + +@usage-- Geting your top element flow +local top_flow = Gui.get_top_flow(game.player) + +]] +Gui.get_top_flow = mod_gui.get_button_flow + +--[[-- Adds an element to be drawn to the top flow when a player joins +@tparam[opt] function authenticator called during toggle or update to decide if the element should be visible +@treturn table the new element define that is used to register events to this element + +@usage-- Adding the example button +example_button:add_to_top_flow(function(player) + -- example button will only show when game time is less than 1 minute + return player.online_time < 3600 +end) + +]] +function Gui._prototype_element:add_to_top_flow(authenticator) + Gui.top_elements[self.name] = authenticator or true + return self +end + +--[[-- Updates the visible states of all the elements on a players top flow +@tparam LuaPlayer player the player that you want to update the flow for + +@usage-- Update your flow +Gui.update_top_flow(game.player) + +]] +function Gui.update_top_flow(player) + local top_flow = Gui.get_top_flow(player) + local hide_button = top_flow[hide_top_flow] + local is_visible = hide_button.visible + + -- Set the visible state of all elements in the flow + for name,authenticator in pairs(Gui.top_elements) do + -- Ensure the element exists + local element = top_flow[name] + if not element then + element = Gui.defines[name](top_flow) + end + + -- Set the visible state + element.visible = is_visible and authenticator(player) or false + end +end + +--[[-- Toggles the visible states of all the elements on a players top flow +@tparam LuaPlayer player the player that you want to toggle the flow for +@tparam[opt] boolean state if given then the state will be set to this state +@treturn boolean the new visible state of the top flow + +@usage-- Toggle your flow +Gui.toggle_top_flow(game.player) + +@usage-- Open your top flow +Gui.toggle_top_flow(game.player,true) + +]] +function Gui.toggle_top_flow(player,state) + -- Get the top flow and hide button + local top_flow = Gui.get_top_flow(player) + if state == nil then state = not top_flow.visible end + + -- Change the visiblty of the flow + local left_flow = Gui.get_left_flow(player) + local show_button = left_flow.gui_core_buttons[show_top_flow] + show_button.visible = not state + top_flow.visible = state + + return state +end \ No newline at end of file From 0db55650240c1bf120849588e979d552a2f03e9b Mon Sep 17 00:00:00 2001 From: badgamernl Date: Mon, 24 Feb 2020 23:35:25 +0100 Subject: [PATCH 29/81] Added ability to chain raise_custom_event --- expcore/gui/prototype.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 75365bd1..21f26033 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -246,6 +246,7 @@ end --[[-- Raise the handler which is attached to any event; external use should be limited to custom events @tparam table event the event table bassed to the handler, must include fields: name, element +@treturn table the element define so more events can be raised @usage Raising a custom event element_define:raise_custom_event{ @@ -258,20 +259,20 @@ function Gui._prototype_element:raise_custom_event(event) -- Check the element is valid local element = event.element if not element or not element.valid then - return + return self end -- Get the event handler for this element local handler = self[event.name] if not handler then - return + return self end -- Get the player for this event local player_index = event.player_index or element.player_index local player = game.players[player_index] if not player or not player.valid then - return + return self end event.player = player @@ -279,6 +280,7 @@ function Gui._prototype_element:raise_custom_event(event) if not success then error('There as been an error with an event handler for a gui element:\n\t'..err) end + return self end -- This function is used to register a link between element define events and the events in the factorio api From 1273de4e86a2e1b39925d55a360417ddfbc150bc Mon Sep 17 00:00:00 2001 From: badgamernl Date: Mon, 24 Feb 2020 23:43:41 +0100 Subject: [PATCH 30/81] Added custom event on_visibility_changed_by_click Fixed warp flow issue because of this --- expcore/gui/left_flow.lua | 51 ++++++++++++++++++++++++++++++++++++--- expcore/gui/prototype.lua | 7 ++++++ modules/gui/warp-list.lua | 7 +++--- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index e21a10c1..64243932 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -52,7 +52,7 @@ end) ]] function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) - return Gui.element{ + local button = Gui.element{ type = 'sprite-button', sprite = sprite, tooltip = tooltip, @@ -62,9 +62,26 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) padding = -2 } :add_to_top_flow(authenticator) - :on_click(function(player,_,_) - Gui.toggle_left_element(player, element_define) + + -- Add on_click handler to handle click events comming from the player + button:on_click(function(player,_,_) + local top_flow = Gui.get_top_flow(player) + local element = top_flow[button.name] + local visibility_state = Gui.toggle_left_element(player, element_define) + + -- Raise custom event that tells listening elements if the element has changed visibility by a player clicking + -- Used in warp gui to handle the keep open logic + button:raise_custom_event{ + name = Gui.events.on_visibility_changed_by_click, + element = element, + state = visibility_state + } end) + + -- Add property to the left flow element with the name of the button + -- This is for the ability to reverse lookup the button from the left flow element + element_define.toolbar_button = button.name + return button end --[[-- Draw all the left elements onto the left flow, internal use only @@ -137,6 +154,34 @@ function Gui.hide_left_flow(player) hide_button.visible = false for name,_ in pairs(Gui.left_elements) do left_flow[name].visible = false + + -- Get the assosiated element define + local element_define = Gui.defines[name] + local top_flow = Gui.get_top_flow(player) + + -- Check if the the element has a button attached + if not element_define.toolbar_button then + goto hide_left_flow_end + end + + -- Check if the topflow contains the button + local button = top_flow[element_define.toolbar_button] + if not button then + goto hide_left_flow_end + end + + -- Get the button define from the reverse lookup on the element + local button_define = Gui.defines[element_define.toolbar_button] + + -- Raise the custom event if all of the top checks have passed + button_define:raise_custom_event{ + name = Gui.events.on_visibility_changed_by_click, + element = button, + state = false + } + + -- Label for the end of the loop + ::hide_left_flow_end:: end end diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 21f26033..aedcf736 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -350,5 +350,12 @@ Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on -- @tparam function handler the event handler which will be called Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) +--- Element Events. +-- @section customEvents +Gui.events = { + -- Triggered when a user changed the visibility of a left flow element by clicking a button + on_visibility_changed_by_click = 'on_visibility_changed_by_click' +} + -- Module return return Gui \ No newline at end of file diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 66626780..7f63395c 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -439,9 +439,10 @@ end) Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',config.standard_proximity_radius},warp_list_container, function(player) return Roles.player_allowed(player,'gui/warp-list') end) -:on_click(function(player,_,_) - local visible_state = Gui.toggle_left_element(player, warp_list_container) - keep_gui_open[player.name] = visible_state +:on_custom_event(Gui.events.on_visibility_changed_by_click, function(player,_,event) + local state = event.state -- true if visible, false if invisible + -- Set gui keep open state for player that clicked the button + keep_gui_open[player.name] = state end) --- When the name of a warp is updated this is triggered From c2676d3bd691bd30c39e239526717370052aeea3 Mon Sep 17 00:00:00 2001 From: badgamernl Date: Tue, 25 Feb 2020 22:41:41 +0100 Subject: [PATCH 31/81] Added ChatBot Async commands: - makepopcorn - passsomesnaps - makecocktail - makecoffee - orderpizza - maketea - meadplease - passabeer --- config/chat_reply.lua | 48 +++++++++++++++++++++++++++++++++++++++++++ locale/en/addons.cfg | 21 +++++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/config/chat_reply.lua b/config/chat_reply.lua index fc8dee5c..81cf57c5 100644 --- a/config/chat_reply.lua +++ b/config/chat_reply.lua @@ -1,8 +1,13 @@ --- This file defines the different triggers for the chat bot -- @config Chat-Reply +local Async = require 'expcore.async' local format_time = ext_require('expcore.common','format_time') --- @dep expcore.common +local async_message = Async.register(function(player, message) + player.print(message) +end) + return { allow_command_prefix_for_messages = true, --- @setting allow_command_prefix_for_messages when true any message trigger will print to all player when prefixed messages = { --- @setting messages will trigger when ever the word is said @@ -65,5 +70,48 @@ return { ['evolution']=function() return {'chat-bot.current-evolution',string.format('%.2f',game.forces['enemy'].evolution_factor)} end, + ['makepopcorn']=function(player) + local timeout = math.floor(180*(math.random()+0.5)) + Async(async_message,player,{'chat-bot.reply',{'chat-bot.get-popcorn-1'}}) + Async.wait(timeout,async_message,player,{'chat-bot.reply',{'chat-bot.get-popcorn-2',player.name}}) + end, + ['passsomesnaps']=function(player) + local timeout = math.floor(180*(math.random()+0.5)) + Async(async_message,player,{'chat-bot.reply',{'chat-bot.get-snaps-1'}}) + Async.wait(timeout,async_message,player,{'chat-bot.reply',{'chat-bot.get-snaps-2',player.name}}) + Async.wait(timeout*(math.random()+0.5),async_message,player,{'chat-bot.reply',{'chat-bot.get-snaps-3',player.name}}) + end, + ['makecocktail']=function(player) + local timeout = math.floor(180*(math.random()+0.5)) + Async(async_message,player,{'chat-bot.reply',{'chat-bot.get-cocktail-1'}}) + Async.wait(timeout,async_message,player,{'chat-bot.reply',{'chat-bot.get-cocktail-2',player.name}}) + Async.wait(timeout*(math.random()+0.5),async_message,player,{'chat-bot.reply',{'chat-bot.get-cocktail-3',player.name}}) + end, + ['makecoffee']=function(player) + local timeout = math.floor(180*(math.random()+0.5)) + Async(async_message,player,{'chat-bot.reply',{'chat-bot.make-coffee-1'}}) + Async.wait(timeout,async_message,player,{'chat-bot.reply',{'chat-bot.make-coffee-2',player.name}}) + end, + ['orderpizza']=function(player) + local timeout = math.floor(180*(math.random()+0.5)) + Async(async_message,player,{'chat-bot.reply',{'chat-bot.order-pizza-1'}}) + Async.wait(timeout,async_message,player,{'chat-bot.reply',{'chat-bot.order-pizza-2',player.name}}) + Async.wait(timeout*(math.random()+0.5),async_message,player,{'chat-bot.reply',{'chat-bot.order-pizza-3',player.name}}) + end, + ['maketea']=function(player) + local timeout = math.floor(180*(math.random()+0.5)) + Async(async_message,player,{'chat-bot.reply',{'chat-bot.make-tea-1'}}) + Async.wait(timeout,async_message,player,{'chat-bot.reply',{'chat-bot.make-tea-2',player.name}}) + end, + ['meadplease']=function(player) + local timeout = math.floor(180*(math.random()+0.5)) + Async(async_message,player,{'chat-bot.reply',{'chat-bot.get-mead-1'}}) + Async.wait(timeout,async_message,player,{'chat-bot.reply',{'chat-bot.get-mead-2',player.name}}) + end, + ['passabeer']=function(player) + local timeout = math.floor(180*(math.random()+0.5)) + Async(async_message,player,{'chat-bot.reply',{'chat-bot.get-beer-1'}}) + Async.wait(timeout,async_message,player,{'chat-bot.reply',{'chat-bot.get-beer-2',player.name}}) + end } } diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index d0588e20..a039c695 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -57,8 +57,25 @@ riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ ‹ ‹\(´ω` )/››‹ loops=NO LOOPS; LOOPS ARE BAD; JUST NO LOOPS!!!!!; IF YOU MAKE A LOOP.... IT WILL NOT END WELL!!!!!!! lenny=( ͡° ͜ʖ ͡°) hodor=Hodor - - +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. +get-snaps-1=Pouring the glasses and finding the correct song book... +get-snaps-2=Singing a song...🎤🎶 +get-snaps-3=schkå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.🍸 +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. ☕ +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-tea-1= ☕ Boiling the water... ☕ +make-tea-2= ☕ __1__ your tea is done! ☕ +get-mead-1= Filling the drinking horn +get-mead-2= Skål! +get-beer-1= 🍺 Pouring A Glass 🍺 +get-beer-2= 🍻 Chears Mate 🍻 [greetings] greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color] From 3aa77227ca9d9ab17d3eef9962c84055e27b1263 Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 00:35:55 +0100 Subject: [PATCH 32/81] Removed goto usage --- expcore/gui/left_flow.lua | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 64243932..74003f15 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -160,28 +160,20 @@ function Gui.hide_left_flow(player) local top_flow = Gui.get_top_flow(player) -- Check if the the element has a button attached - if not element_define.toolbar_button then - goto hide_left_flow_end + if element_define.toolbar_button then + -- Check if the topflow contains the button + local button = top_flow[element_define.toolbar_button] + if button then + -- Get the button define from the reverse lookup on the element + local button_define = Gui.defines[element_define.toolbar_button] + -- Raise the custom event if all of the top checks have passed + button_define:raise_custom_event{ + name = Gui.events.on_visibility_changed_by_click, + element = button, + state = false + } + end end - - -- Check if the topflow contains the button - local button = top_flow[element_define.toolbar_button] - if not button then - goto hide_left_flow_end - end - - -- Get the button define from the reverse lookup on the element - local button_define = Gui.defines[element_define.toolbar_button] - - -- Raise the custom event if all of the top checks have passed - button_define:raise_custom_event{ - name = Gui.events.on_visibility_changed_by_click, - element = button, - state = false - } - - -- Label for the end of the loop - ::hide_left_flow_end:: end end From efd9c7b609f64c1d4ae23f090337eb16d2cfa1ec Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 00:41:18 +0100 Subject: [PATCH 33/81] Renamed Gui.event to Gui.custom_event --- expcore/gui/left_flow.lua | 4 ++-- expcore/gui/prototype.lua | 4 ++-- modules/gui/warp-list.lua | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 74003f15..255823c5 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -72,7 +72,7 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) -- Raise custom event that tells listening elements if the element has changed visibility by a player clicking -- Used in warp gui to handle the keep open logic button:raise_custom_event{ - name = Gui.events.on_visibility_changed_by_click, + name = Gui.custom_events.on_visibility_changed_by_click, element = element, state = visibility_state } @@ -168,7 +168,7 @@ function Gui.hide_left_flow(player) local button_define = Gui.defines[element_define.toolbar_button] -- Raise the custom event if all of the top checks have passed button_define:raise_custom_event{ - name = Gui.events.on_visibility_changed_by_click, + name = Gui.custom_events.on_visibility_changed_by_click, element = button, state = false } diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index aedcf736..6e7e6c5f 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -350,9 +350,9 @@ Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on -- @tparam function handler the event handler which will be called Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) ---- Element Events. +--- Custom element events. -- @section customEvents -Gui.events = { +Gui.custom_event = { -- Triggered when a user changed the visibility of a left flow element by clicking a button on_visibility_changed_by_click = 'on_visibility_changed_by_click' } diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 7f63395c..5e24af6c 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -439,7 +439,7 @@ end) Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',config.standard_proximity_radius},warp_list_container, function(player) return Roles.player_allowed(player,'gui/warp-list') end) -:on_custom_event(Gui.events.on_visibility_changed_by_click, function(player,_,event) +:on_custom_event(Gui.custom_events.on_visibility_changed_by_click, function(player,_,event) local state = event.state -- true if visible, false if invisible -- Set gui keep open state for player that clicked the button keep_gui_open[player.name] = state From 8e9325fc0cf96dac9825a404796ed3d4283f1da6 Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 00:42:33 +0100 Subject: [PATCH 34/81] Changed keep open to be a one liner --- modules/gui/warp-list.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 5e24af6c..b6954687 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -440,9 +440,8 @@ Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',c return Roles.player_allowed(player,'gui/warp-list') end) :on_custom_event(Gui.custom_events.on_visibility_changed_by_click, function(player,_,event) - local state = event.state -- true if visible, false if invisible - -- Set gui keep open state for player that clicked the button - keep_gui_open[player.name] = state + -- Set gui keep open state for player that clicked the button: true if visible, false if invisible + keep_gui_open[player.name] = event.state end) --- When the name of a warp is updated this is triggered From 2d90d1dcdd3071c7820a0083f006e4f5b5e61dde Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 00:49:57 +0100 Subject: [PATCH 35/81] Rerenamed events --- expcore/gui/left_flow.lua | 4 ++-- expcore/gui/prototype.lua | 7 +++---- modules/gui/warp-list.lua | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 255823c5..74003f15 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -72,7 +72,7 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) -- Raise custom event that tells listening elements if the element has changed visibility by a player clicking -- Used in warp gui to handle the keep open logic button:raise_custom_event{ - name = Gui.custom_events.on_visibility_changed_by_click, + name = Gui.events.on_visibility_changed_by_click, element = element, state = visibility_state } @@ -168,7 +168,7 @@ function Gui.hide_left_flow(player) local button_define = Gui.defines[element_define.toolbar_button] -- Raise the custom event if all of the top checks have passed button_define:raise_custom_event{ - name = Gui.custom_events.on_visibility_changed_by_click, + name = Gui.events.on_visibility_changed_by_click, element = button, state = false } diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 6e7e6c5f..b307da02 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -352,10 +352,9 @@ Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.o --- Custom element events. -- @section customEvents -Gui.custom_event = { - -- Triggered when a user changed the visibility of a left flow element by clicking a button - on_visibility_changed_by_click = 'on_visibility_changed_by_click' -} + +-- Triggered when a user changed the visibility of a left flow element by clicking a button +Gui.events.on_visibility_changed_by_click = 'on_visibility_changed_by_click' -- Module return return Gui \ No newline at end of file diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index b6954687..595a3ba2 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -439,7 +439,7 @@ end) Gui.left_toolbar_button('item/'..config.default_icon,{'warp-list.main-tooltip',config.standard_proximity_radius},warp_list_container, function(player) return Roles.player_allowed(player,'gui/warp-list') end) -:on_custom_event(Gui.custom_events.on_visibility_changed_by_click, function(player,_,event) +:on_custom_event(Gui.events.on_visibility_changed_by_click, function(player,_,event) -- Set gui keep open state for player that clicked the button: true if visible, false if invisible keep_gui_open[player.name] = event.state end) From 76f86b7a970e34dccefafd71deb207bca5581e7b Mon Sep 17 00:00:00 2001 From: badgamernl Date: Wed, 26 Feb 2020 01:36:40 +0100 Subject: [PATCH 36/81] Added toolbar button color for open flows * Added top flow button style `Gui.top_flow_button_visible_style` * Added function to style toolbar buttons `Gui.left_toolbar_button_style` * Modified code to call the toolbar button style function --- expcore/gui/left_flow.lua | 50 +++++++++++++++++++++++++++++++++++++++ expcore/gui/top_flow.lua | 4 ++++ 2 files changed, 54 insertions(+) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 74003f15..53c37394 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -39,6 +39,28 @@ function Gui._prototype_element:add_to_left_flow(open_on_join) return self end +--[[-- Styles the top flow button depending on the state given +@tparam LuaGuiElement the button element to style +@tparam boolean state The state the button is in + +@usage-- Sets the button to the visible style +Gui.left_toolbar_button_style(button, true) + +@usage-- Sets the button to the hidden style +Gui.left_toolbar_button_style(button, false) + +]] +function Gui.left_toolbar_button_style(button, state) + if state then + button.style = Gui.top_flow_button_visible_style + else + button.style = Gui.top_flow_button_style + end + button.style.minimal_width = 36 + button.style.height = 36 + button.style.padding = -2 +end + --[[-- Button which can be used to toggle a left element, placed on the top flow @tparam string sprite the sprite that you want to use on the button @tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have @@ -59,6 +81,8 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) style = Gui.top_flow_button_style } :style{ + minimal_width = 36, + height = 36, padding = -2 } :add_to_top_flow(authenticator) @@ -113,6 +137,20 @@ function Gui.draw_left_flow(player) -- Set the visible state of the element left_element.visible = visible show_hide_button = show_hide_button or visible + + -- Get the assosiated element define + local element_define = Gui.defines[name] + local top_flow = Gui.get_top_flow(player) + + -- Check if the the element has a button attached + if element_define.toolbar_button then + -- Check if the topflow contains the button + local button = top_flow[element_define.toolbar_button] + if button then + -- Style the button + Gui.left_toolbar_button_style(button, visible) + end + end end hide_button.visible = show_hide_button @@ -164,6 +202,8 @@ function Gui.hide_left_flow(player) -- Check if the topflow contains the button local button = top_flow[element_define.toolbar_button] if button then + -- Style the button + Gui.left_toolbar_button_style(button, false) -- Get the button define from the reverse lookup on the element local button_define = Gui.defines[element_define.toolbar_button] -- Raise the custom event if all of the top checks have passed @@ -206,6 +246,7 @@ Gui.toggle_top_flow(game.player,example_flow_with_button,true) ]] function Gui.toggle_left_element(player,element_define,state) local left_flow = Gui.get_left_flow(player) + local top_flow = Gui.get_top_flow(player) -- Set the visible state local element = left_flow[element_define.name] @@ -213,5 +254,14 @@ function Gui.toggle_left_element(player,element_define,state) element.visible = state Gui.update_left_flow(player) + -- Check if the the element has a button attached + if element_define.toolbar_button then + -- Check if the topflow contains the button + local button = top_flow[element_define.toolbar_button] + if button then + -- Style the button + Gui.left_toolbar_button_style(button, state) + end + end return state end \ No newline at end of file diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua index b35eb2b0..f4d5de9f 100644 --- a/expcore/gui/top_flow.lua +++ b/expcore/gui/top_flow.lua @@ -20,6 +20,10 @@ Gui.top_elements = {} -- @field Gui.top_flow_button_style Gui.top_flow_button_style = mod_gui.button_style +--- The style that should be used for buttons on the top flow where the flow it opens is visible +-- @field Gui.top_flow_button_visible_style +Gui.top_flow_button_visible_style = 'menu_button_continue' + --[[-- Gets the flow which contains the elements for the top flow @function Gui.get_top_flow(player) @tparam LuaPlayer player the player that you want to get the flow for From c9514f22e7025f2a59df07b6effd2f9e80c7450f Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 27 Feb 2020 20:53:03 +0000 Subject: [PATCH 37/81] Added fast tree removeal --- config/_file_loader.lua | 1 + config/roles.lua | 2 ++ modules/addons/tree-decon.lua | 61 +++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 modules/addons/tree-decon.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index e37d3a0d..6c6c0c0d 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -41,6 +41,7 @@ return { 'modules.addons.random-player-colours', 'modules.addons.discord-alerts', 'modules.addons.chat-reply', + 'modules.addons.tree-decon', -- GUI 'modules.gui.rocket-info', 'modules.gui.science-info', diff --git a/config/roles.lua b/config/roles.lua index dbdb3c31..b25704a6 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -90,6 +90,7 @@ Roles.new_role('Moderator','Mod') 'command/return', 'gui/rocket-info/toggle-active', 'gui/rocket-info/remote_launch', + 'fast-tree-decon', } Roles.new_role('Trainee','TrMod') @@ -138,6 +139,7 @@ Roles.new_role('Pay to Win','P2W') 'command/home-set', 'command/home-get', 'command/return', + 'fast-tree-decon', } Roles.new_role('Donator','Don') diff --git a/modules/addons/tree-decon.lua b/modules/addons/tree-decon.lua new file mode 100644 index 00000000..ac065342 --- /dev/null +++ b/modules/addons/tree-decon.lua @@ -0,0 +1,61 @@ +--- Makes trees which are marked for decon "decay" quickly to allow faster building +-- @addon Tree-Decon + +local Event = require 'utils.event' --- @dep utils.event +local Game = require 'utils.game' --- @dep utils.game +local Global = require 'utils.global' --- @dep utils.global +local Roles = require 'expcore.roles' --- @dep expcore.roles + +-- Global queue used to store trees that need to be removed, also chache for player roles +local chache = {} +local tree_queue = { _head=0 } +Global.register({ tree_queue, chache }, function(tbl) + tree_queue = tbl[1] + chache = tbl[2] +end) + +-- Add trees to queue when marked, only allows simple entities and for players with role permission +Event.add(defines.events.on_marked_for_deconstruction, function(event) + -- Check the player is allowed fast decon + local player = Game.get_player_by_index(event.player_index) + if chache[player.name] ~= true and not Roles.player_allowed(player, 'fast-tree-decon') then + chache[player.name] = false + return + end + chache[player.name] = true + + -- Check that the entity is allowed to be isntant deconed + local head = tree_queue._head + 1 + local entity = event.entity + if entity and entity.valid and not entity.last_user and entity.type ~= 'cliff' then + tree_queue[head] = entity + tree_queue._head = head + end +end) + +-- Remove trees at random till the queue is empty +Event.add(defines.events.on_tick, function() + local head = tree_queue._head + if head == 0 then return end + + local max_remove = math.floor(head/100)+1 + local remove_count = math.random(0, max_remove) + while remove_count > 0 do + local remove_index = math.random(1,head) + local entity = tree_queue[remove_index] + tree_queue[remove_index] = tree_queue[head] + head = head - 1 + if entity and entity.valid then + remove_count = remove_count - 1 + entity.destroy() + end + end + tree_queue._head = head +end) + +-- Clear the chache +Event.on_nth_tick(300, function() + for key,_ in pairs(chache) do + chache[key] = nil + end +end) \ No newline at end of file From 28a19b46be0dff5cd1c522fef0cbafca89956aac Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 6 Mar 2020 17:06:03 +0000 Subject: [PATCH 38/81] Added verify message --- config/chat_reply.lua | 3 +++ locale/en/addons.cfg | 1 + 2 files changed, 4 insertions(+) diff --git a/config/chat_reply.lua b/config/chat_reply.lua index 81cf57c5..8b8343c5 100644 --- a/config/chat_reply.lua +++ b/config/chat_reply.lua @@ -46,6 +46,9 @@ return { ['time']=function() return {'chat-bot.map-time',format_time(game.tick,{days=true,hours=true,minutes=true,seconds=true,long=true})} end, + ['r!verify']=function(player) + return {'chat-bot.verify',player.name} + end, }, command_admin_only = false, --- @setting command_admin_only when true will only allow chat commands for admins command_permission = 'command/chat-bot', --- @setting command_permission the permission used to allow command prefixes diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index 22f8c32d..e526e53f 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -76,6 +76,7 @@ get-mead-1= Filling the drinking horn get-mead-2= Skål! get-beer-1= 🍺 Pouring A Glass 🍺 get-beer-2= 🍻 Chears Mate 🍻 +verify=Please return to our discord and type r!verify __1__ [greetings] greet=[color=0,1,0] Welcome to explosive gaming community server! If you like the server join our discord: __1__ [/color] \ No newline at end of file From c2c535848d9170651a79eb8a92dffe4ffdc0b5cd Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 17 Mar 2020 22:36:52 +0000 Subject: [PATCH 39/81] Cleaned core gui files --- expcore/gui/core_defines.lua | 8 +- expcore/gui/defines.lua | 82 +++++------ expcore/gui/helper_functions.lua | 18 +-- expcore/gui/left_flow.lua | 58 ++++---- expcore/gui/prototype.lua | 228 +++++++++++++++++++------------ expcore/gui/top_flow.lua | 37 ++--- modules/gui/player-list.lua | 2 +- modules/gui/rocket-info.lua | 4 +- modules/gui/science-info.lua | 2 +- modules/gui/task-list.lua | 2 +- modules/gui/warp-list.lua | 2 +- 11 files changed, 250 insertions(+), 193 deletions(-) diff --git a/expcore/gui/core_defines.lua b/expcore/gui/core_defines.lua index 5c26bea7..8ae38fbe 100644 --- a/expcore/gui/core_defines.lua +++ b/expcore/gui/core_defines.lua @@ -1,5 +1,5 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Gui defines that are used internally by the gui system @module Gui ]] @@ -9,7 +9,7 @@ local Event = require 'utils.event' --- @dep utils.event --- Core Defines. -- @section coreDefines ---- Button which toggles the top flow elements, shows inside top flow +--- Button which toggles the top flow elements, version which shows inside the top flow when top flow is visible -- @element hide_top_flow local hide_top_flow = Gui.element{ @@ -28,7 +28,7 @@ Gui.element{ end) Gui.core_defines.hide_top_flow = hide_top_flow ---- Button which toggles the top flow elements, shows inside left flow +--- Button which toggles the top flow elements, version which shows inside the left flow when top flow is hidden -- @element show_top_flow local show_top_flow = Gui.element{ @@ -47,7 +47,7 @@ Gui.element{ end) Gui.core_defines.show_top_flow = show_top_flow ---- Button which hides the elements in the left flow +--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible -- @element hide_left_flow local hide_left_flow = Gui.element{ diff --git a/expcore/gui/defines.lua b/expcore/gui/defines.lua index db52d8ca..d062078c 100644 --- a/expcore/gui/defines.lua +++ b/expcore/gui/defines.lua @@ -1,16 +1,19 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Common defines that are used by other modules, non of these are used internally @module Gui ]] local Gui = require 'expcore.gui.prototype' ---[[-- Draw a flow that has custom element alignments, default is right align +--- Defines. +-- @section defines + +--[[-- Draw a flow used to align its child elements, default is right align @element Gui.alignment -@tparam LuaGuiElement parent the parent element that the alignment flow will be added to +@tparam LuaGuiElement parent the parent element to which the alignment will be added +@tparam[opt='alignment'] string name the name of the alignment flow which is added @tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow @tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow -@tparam[opt='alignment'] string name the name of the alignment flow @treturn LuaGuiElement the alignment flow that was created @usage-- Adding a right align flow @@ -21,13 +24,13 @@ local alignment = Gui.alignment(element,'example_center_top_alignment','center', ]] Gui.alignment = -Gui.element(function(_,parent,_,_,name) +Gui.element(function(_,parent,name,_,_) return parent.add{ name = name or 'alignment', type = 'flow', } end) -:style(function(style,_,horizontal_align,vertical_align,_) +:style(function(style,_,_,horizontal_align,vertical_align) style.padding = {1,2} style.vertical_align = vertical_align or 'center' style.horizontal_align = horizontal_align or 'right' @@ -37,18 +40,18 @@ end) --[[-- Draw a scroll pane that has a table inside of it @element Gui.scroll_table -@tparam LuaGuiElement parent the parent element that the scroll table will be added to +@tparam LuaGuiElement parent the parent element to which the scroll table will be added @tparam number height the maximum height for the scroll pane @tparam number column_count the number of columns that the table will have -@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called 'table' +@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called "table" @treturn LuaGuiElement the table that was created @usage-- Adding a scroll table with max height of 200 and column count of 3 -local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3) +local scroll_table = Gui.scroll_table(element,200,3) ]] Gui.scroll_table = -Gui.element(function(_,parent,_,column_count,name) +Gui.element(function(_,parent,height,column_count,name) -- Draw the scroll local scroll_pane = parent.add{ @@ -60,6 +63,12 @@ Gui.element(function(_,parent,_,column_count,name) style = 'scroll_pane_under_subheader' } + -- Set the style of the scroll pane + local scroll_style = scroll_pane.style + scroll_style.padding = {1,3} + scroll_style.maximal_height = height + scroll_style.horizontally_stretchable = true + -- Draw the table local scroll_table = scroll_pane.add{ @@ -71,35 +80,27 @@ Gui.element(function(_,parent,_,column_count,name) -- Return the scroll table return scroll_table end) -:style(function(style,element,height,_,_) - -- Change the style of the scroll - local scroll_style = element.parent.style - scroll_style.padding = {1,3} - scroll_style.maximal_height = height - scroll_style.horizontally_stretchable = true +:style{ + padding = 0, + cell_padding = 0, + vertical_align = 'center', + horizontally_stretchable = true +} - -- Change the style of the table - style.padding = 0 - style.cell_padding = 0 - style.vertical_align = 'center' - style.horizontally_stretchable = true -end) - ---[[-- Used to add a header to a frame, this has the option for a custom right alignment flow for buttons +--[[-- Used to add a frame with the header style, has the option for a right alignment flow for buttons @element Gui.header -@tparam LuaGuiElement parent the parent element that the header will be added to +@tparam LuaGuiElement parent the parent element to which the header will be added @tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header @tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header -@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons -@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called 'alignment' +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added to the header +@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called "alignment" @treturn LuaGuiElement either the header or the header alignment if add_alignment is true @usage-- Adding a custom header with a label -local header_alignment = Gui.header( +local header = Gui.header( element, 'Example Caption', - 'Example Tooltip', - true + 'Example Tooltip' ) ]] @@ -134,21 +135,20 @@ Gui.element(function(_,parent,caption,tooltip,add_alignment,name) return add_alignment and Gui.alignment(header) or header end) ---[[-- Used to add a footer to a frame, this has the option for a custom right alignment flow for buttons -@element Gui.header -@tparam LuaGuiElement parent the parent element that the footer will be added to +--[[-- Used to add a frame with the footer style, has the option for a right alignment flow for buttons +@element Gui.footer +@tparam LuaGuiElement parent the parent element to which the footer will be added @tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the footer @tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the footer -@tparam[opt=false] boolean add_alignment when true an alignment flow will be added for buttons -@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called 'alignment' +@tparam[opt=false] boolean add_alignment when true an alignment flow will be added to the footer +@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called "alignment" @treturn LuaGuiElement either the footer or the footer alignment if add_alignment is true @usage-- Adding a custom footer with a label -local header_alignment = Gui.footer( +local footer = Gui.footer( element, 'Example Caption', - 'Example Tooltip', - true + 'Example Tooltip' ) ]] @@ -183,10 +183,10 @@ Gui.element(function(_,parent,caption,tooltip,add_alignment,name) return add_alignment and Gui.alignment(footer) or footer end) ---[[-- Used for left frame to add a nice boarder to them and contain them +--[[-- Used for left frames to give them a nice boarder @element Gui.container -@tparam LuaGuiElement parent the parent element that the container will be added to -@tparam string name the name that you want to give the outer frame, often just event_trigger for a left frame +@tparam LuaGuiElement parent the parent element to which the container will be added +@tparam string name the name that you want to give to the outer frame, often just event_trigger @tparam number width the minimal width that the frame will have @usage-- Adding a container as a base diff --git a/expcore/gui/helper_functions.lua b/expcore/gui/helper_functions.lua index 22106718..c303fb15 100644 --- a/expcore/gui/helper_functions.lua +++ b/expcore/gui/helper_functions.lua @@ -1,5 +1,5 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Functions used to help with the use of guis @module Gui ]] @@ -9,7 +9,7 @@ local Gui = require 'expcore.gui.prototype' -- @section helperFunctions --[[-- Get the player that owns a gui element -@tparam LuaGuiElement element the element that you want to get the owner of +@tparam LuaGuiElement element the element to get the owner of @treturn LuaPlayer the player that owns this element @usage-- Geting the owner of an element @@ -22,8 +22,8 @@ function Gui.get_player_from_element(element) end --[[-- Will toggle the enabled state of an element or set it to the one given -@tparam LuaGuiElement element the element that you want to toggle the state of -@tparam[opt] boolean state the state that you want to set +@tparam LuaGuiElement element the element to toggle/set the enabled state of +@tparam[opt] boolean state with given will set the state, else state will be toggled @treturn boolean the new enabled state that the element has @usage-- Toggling the the enabled state @@ -38,8 +38,8 @@ function Gui.toggle_enabled_state(element,state) end --[[-- Will toggle the visible state of an element or set it to the one given -@tparam LuaGuiElement element the element that you want to toggle the state of -@tparam[opt] boolean state the state that you want to set +@tparam LuaGuiElement element the element to toggle/set the visible state of +@tparam[opt] boolean state with given will set the state, else state will be toggled @treturn boolean the new visible state that the element has @usage-- Toggling the the visible state @@ -53,11 +53,11 @@ function Gui.toggle_visible_state(element,state) return state end ---[[-- Destory a gui element without causing any errors, likly if the element may have already been removed +--[[-- Destory a gui element without causing any errors, often because the element was already removed @tparam LuaGuiElement element the element that you want to remove @treturn boolean true if the element was valid and has been removed -@usage-- Likely use case for element not existing +@usage-- Remove a child element if it exists Gui.destroy_if_valid(element[child_name]) ]] @@ -67,7 +67,7 @@ function Gui.destroy_if_valid(element) return true end ---[[-- Returns a table to be used as a style on sprite buttons, produces a sqaure button +--[[-- Returns a table to be used as the style for a sprite buttons, produces a sqaure button @tparam number size the size that you want the button to be @tparam[opt=-2] number padding the padding that you want on the sprite @tparam[opt] table style any extra style settings that you want to have diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 53c37394..cbe83bfa 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -11,23 +11,26 @@ local hide_left_flow = Gui.core_defines.hide_left_flow.name --- Left Flow. -- @section leftFlow ---- Contains the uids of the elements that will show on the left flow and the open on join function +-- Triggered when a user changed the visibility of a left flow element by clicking a button +Gui.events.on_visibility_changed_by_click = 'on_visibility_changed_by_click' + +--- Contains the uids of the elements that will shown on the left flow and their join functions -- @table left_elements Gui.left_elements = {} ---[[-- Gets the flow which contains the elements for the left flow +--[[-- Gets the flow refered to as the left flow, each player has one left flow @function Gui.get_left_flow(player) -@tparam LuaPlayer player the player that you want to get the flow for +@tparam LuaPlayer player the player that you want to get the left flow for @treturn LuaGuiElement the left element flow -@usage-- Geting your left element flow +@usage-- Geting your left flow local left_flow = Gui.get_left_flow(game.player) ]] Gui.get_left_flow = mod_gui.get_frame_flow ---[[-- Adds an element to be drawn to the left flow when a player joins -@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element is visible +--[[-- Sets an element define to be drawn to the left flow when a player joins, includes optional check +@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element should be visible @treturn table the new element define that is used to register events to this element @usage-- Adding the example button @@ -39,7 +42,7 @@ function Gui._prototype_element:add_to_left_flow(open_on_join) return self end ---[[-- Styles the top flow button depending on the state given +--[[-- Styles a top flow button depending on the state given @tparam LuaGuiElement the button element to style @tparam boolean state The state the button is in @@ -61,14 +64,15 @@ function Gui.left_toolbar_button_style(button, state) button.style.padding = -2 end ---[[-- Button which can be used to toggle a left element, placed on the top flow +--[[-- Creates a button on the top flow which will toggle the given element define, the define must exist in the left flow @tparam string sprite the sprite that you want to use on the button @tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have -@tparam table element_define the element define that you want to be toggled on the left flow +@tparam table element_define the element define that you want to have toggled by this button, define must exist on the left flow @tparam[opt] function authenticator used to decide if the button should be visible to a player @usage-- Add a button to toggle a left element -local toolbar_button = Gui.left_toolbar_button('entity/inserter','Nothing to see here',example_flow_with_button,function(player) +local toolbar_button = +Gui.left_toolbar_button('entity/inserter', 'Nothing to see here', example_flow_with_button, function(player) return player.admin end) @@ -108,7 +112,7 @@ function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) return button end ---[[-- Draw all the left elements onto the left flow, internal use only +--[[-- Draw all the left elements onto the left flow, internal use only with on join @tparam LuaPlayer player the player that you want to draw the elements for @usage Draw all the left elements @@ -156,11 +160,11 @@ function Gui.draw_left_flow(player) hide_button.visible = show_hide_button end ---[[-- Update the visible state of the hide left button, also draw left elements if not present +--[[-- Update the visible state of the hide button, can be used to check if any frames are visible @tparam LuaPlayer player the player to update the left flow for @treturn boolean true if any left element is visible -@usage Check if any left elements are visible +@usage-- Check if any left elements are visible local visible = Gui.update_left_flow(player) ]] @@ -185,6 +189,7 @@ Gui.hide_left_flow(game.player) ]] function Gui.hide_left_flow(player) + local top_flow = Gui.get_top_flow(player) local left_flow = Gui.get_left_flow(player) local hide_button = left_flow.gui_core_buttons[hide_left_flow] @@ -193,11 +198,8 @@ function Gui.hide_left_flow(player) for name,_ in pairs(Gui.left_elements) do left_flow[name].visible = false - -- Get the assosiated element define + -- Check if the the element has a toobar button attached local element_define = Gui.defines[name] - local top_flow = Gui.get_top_flow(player) - - -- Check if the the element has a button attached if element_define.toolbar_button then -- Check if the topflow contains the button local button = top_flow[element_define.toolbar_button] @@ -217,13 +219,13 @@ function Gui.hide_left_flow(player) end end ---[[-- Get the element define that is in the left flow -@tparam LuaPlayer player the player that you want tog et the element for -@tparam table element_define the element that you want to get for the player -@treturn LuaGuiElement the gui element linked to this define in the left flow +--[[-- Get the element define that is in the left flow, use in events without an element refrence +@tparam LuaPlayer player the player that you want to get the element for +@tparam table element_define the element that you want to get +@treturn LuaGuiElement the gui element linked to this define for this player @usage-- Get your left element -local frame = Gui.get_left_element(game.player,example_flow_with_button) +local frame = Gui.get_left_element(game.player, example_flow_with_button) ]] function Gui.get_left_element(player,element_define) @@ -231,17 +233,17 @@ function Gui.get_left_element(player,element_define) return left_flow[element_define.name] end ---[[-- Toggles the visible state of a left element for a player +--[[-- Toggles the visible state of a left element for a given player, can be used to set the visible state @tparam LuaPlayer player the player that you want to toggle the element for -@tparam table element_define the element that you want to toggle for the player -@tparam[opt] boolean state if given then the state will be set to this state +@tparam table element_define the element that you want to toggle +@tparam[opt] boolean state with given will set the state, else state will be toggled @treturn boolean the new visible state of the element @usage-- Toggle your example button -Gui.toggle_top_flow(game.player,example_flow_with_button) +Gui.toggle_top_flow(game.player, example_flow_with_button) -@usage-- Open your example button -Gui.toggle_top_flow(game.player,example_flow_with_button,true) +@usage-- Show your example button +Gui.toggle_top_flow(game.player, example_flow_with_button, true) ]] function Gui.toggle_left_element(player,element_define,state) diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index b307da02..3c648c31 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -1,95 +1,148 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Used to simplify gui creation using factory functions called element defines @core Gui @alias Gui -@usage-- Defining a button that prints the player's name +@usage-- To draw your element you only need to call the factory function +-- You are able to pass any other arguments that are used in your custom functions but the first is always the parent element +local example_button_element = example_button(parent_element) + +@usage-- Making a factory function for a button with the caption "Example Button" +-- This method has all the same features as LuaGuiElement.add local example_button = Gui.element{ type = 'button', caption = 'Example Button' } -:on_click(function(player,element,event) - player.print(player.name) -end) -@usage-- Defining a button with a custom style -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:style{ - height = 25, - width = 100 -} -:on_click(function(player,element,event) - player.print(player.name) -end) - -@usage-- Defining a button using a custom function +@usage-- Making a factory function for a button which is contained within a flow +-- This method is for when you still want to register event handlers but cant use the table method local example_flow_with_button = -Gui.element(function(event_trigger,parent) - -- Add the flow the button is in +Gui.element(function(event_trigger,parent,...) + -- ... shows that all other arguments from the factory call are passed to this function + -- Here we are adding a flow which we will then later add a button to local flow = - parent.add{ + parent.add{ -- paraent is the element which is passed to the factory function name = 'example_flow', type = 'flow' } - -- Get the players name - local player = game.players[parent.player_index] - local player_name = player.name - - -- Add the button + -- Now we add the button to the flow that we created earlier local element = flow.add{ - name = event_trigger, + name = event_trigger, -- event_trigger should be the name of any elements you want to trigger your event handlers type = 'button', - caption = 'Example Button: '..player_name + caption = 'Example Button' } - -- Set the style of the button - local style = element.style - style.height = 25 - style.width = 100] - style.font_color = player.color - - -- Return the element + -- You must return a new element, this is so styles can be applied and returned to the caller + -- You may return any of your elements that you added, consider the context in which it will be used for which should be returned return element end) -:on_click(function(player,element,event) - player.print(player.name) + +@usage-- Styles can be added to any element define, simplest way mimics LuaGuiElement.style[key] = value +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here +} +:style{ + height = 25, -- same as element.style.height = 25 + width = 100 -- same as element.style.width = 25 +} + +@usage-- Styles can also have a custom function when the style is dynamic and depends on other factors +-- Use this method if your style is dynamic and depends on other factors +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here +} +:style(function(style,element,...) + -- style is the current style object for the elemenent + -- element is the element that is being changed + -- ... shows that all other arguments from the factory call are passed to this function + local player = game.players[element.player_index] + style.height = 25 + style.width = 100 + style.font_color = player.color end) -@usage-- Drawing an element -local exmple_button_element = example_button(parent) -local example_flow_with_button = example_flow_with_button(parent) +@usage-- You are able to register event handlers to your elements, these can be factorio events or custom ones +-- All events are checked to be valid before raising any handlers, this means element.valid = true and player.valid = true +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:on_click(function(player,element,event) + -- player is the player who interacted with the element to cause the event + -- element is a refrence to the element which caused the event + -- event is a raw refrence to the event data if player and element are not enough + player.print('Clicked: '..element.name) +end) + +@usage-- Example from core_defines, Gui.core_defines.hide_left_flow, called like: hide_left_flow(parent_element) +--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible +-- @element hide_left_flow +local hide_left_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + style = 'tool_button', + tooltip = {'expcore-gui.left-button-tooltip'} +} +:style{ + padding = -3, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.hide_left_flow(player) +end) + +@usage-- Eample from defines, Gui.alignment, called like: Gui.alignment(parent, name, horizontal_align, vertical_align) +-- Notice how _ are used to blank arguments that are not needed in that context and how they line up with above +Gui.alignment = +Gui.element(function(_,parent,name,_,_) + return parent.add{ + name = name or 'alignment', + type = 'flow', + } +end) +:style(function(style,_,_,horizontal_align,vertical_align) + style.padding = {1,2} + style.vertical_align = vertical_align or 'center' + style.horizontal_align = horizontal_align or 'right' + style.vertically_stretchable = style.vertical_align ~= 'center' + style.horizontally_stretchable = style.horizontal_align ~= 'center' +end) ]] local Event = require 'utils.event' --- @dep utils.event local Gui = { - --- The current highest uid that is being used, will not increase during runtime + --- The current highest uid that is being used by a define, will not increase during runtime -- @field uid uid = 0, - --- An index of the element deinfes which are used by the core gui system - -- @table core_defines - core_defines = {}, - --- Table of all the elements which have been registed with the draw function and event handlers - -- @table defines - defines = {}, - --- Table of all custom events that are used by element defines, used to avoid conflicts + --- String indexed table used to avoid conflict with custom event names, similar to how defines.events works -- @table events events = {}, - --- An index used for debuging to find the file where different elements where registered + --- Uid indexed array that stores all the factory functions that were defined, no new values will be added during runtime + -- @table defines + defines = {}, + --- An string indexed table of all the defines which are used by the core of the gui system, used for internal refrence + -- @table core_defines + core_defines = {}, + --- Used to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debuging -- @table file_paths file_paths = {}, - --- An index used for debuging to show more data on element defines + --- Used to store extra infomation about elements as they get defined such as the params used and event handlers registered to them -- @table debug_info debug_info = {}, - --- The element prototype which is returned from Gui.element + --- The prototype used to store the functions of an element define -- @table _prototype_element _prototype_element = {}, --- The prototype metatable applied to new element defines @@ -108,28 +161,33 @@ Gui._mt_element.__index = Gui._prototype_element --- Element Define. -- @section elementDefine ---[[-- Base function used to define new elements, can be used with a table or with a function -@tparam ?table|function element_define used to define how the element is draw, using a table is the simplist way of doing this -@treturn table the new element define that is used to register events to this element +--[[-- Used to define new elements for your gui, can be used like LuaGuiElement.add or a custom function +@tparam ?table|function element_define the define information for the gui element, same data as LuaGuiElement.add, or a custom function may be used +@treturn table the new element define, this can be considered a factory for the element which can be called to draw the element to any other element -@usage-- Defining an element with a table +@usage-- Using element defines like LuaGuiElement.add +-- This returns a factory function to draw a button with the caption "Example Button" local example_button = Gui.element{ type = 'button', caption = 'Example Button' } -@usage-- Defining an element with a function +@usage-- Using element defines with a custom factory function +-- This method can be used if you still want to be able register event handlers but it is too complex to be compatible with LuaGuiElement.add local example_flow_with_button = Gui.element(function(event_trigger,parent,...) - -- Add the flow the button is in + -- ... shows that all other arguments from the factory call are passed to this function + -- parent is the element which was passed to the factory function where you should add your new element + -- here we are adding a flow which we will then later add a button to local flow = parent.add{ name = 'example_flow', type = 'flow' } - -- Add the button + -- event_trigger should be the name of any elements you want to trigger your event handlers, such as on_click or on_state_changed + -- now we add the button to the flow that we created earlier local element = flow.add{ name = event_trigger, @@ -137,12 +195,8 @@ Gui.element(function(event_trigger,parent,...) caption = 'Example Button' } - -- Set the style of the button - local style = element.style - style.height = 25 - style.width = 100 - - -- Return the element + -- you must return your new element, this is so styles can be applied and returned to the caller + -- you may return any of your elements that you add, consider the context in which it will be used for what should be returned return element end) @@ -179,28 +233,34 @@ function Gui.element(element_define) return element end ---[[-- Extension of Gui.element when using the table method, values applied after the element is drawn -@tparam ?table|function style_define used to define how the style is applied, using a table is the simplist way of doing this -@treturn table the new element define that is used to register events to this element +--[[-- Used to extent your element define with a style factory, this style will be applied to your element when created, can also be a custom function +@tparam ?table|function style_define style table where each key and value pair is treated like LuaGuiElement.style[key] = value, a custom function can be used +@treturn table the element define is returned to allow for event handlers to be registered -@usage-- Setting the height and width of the example button +@usage-- Using the table method of setting the style local example_button = Gui.element{ type = 'button', - caption = 'Example Button' + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here } :style{ - height = 25, - width = 100 + height = 25, -- same as element.style.height = 25 + width = 100 -- same as element.style.width = 25 } -@usage-- Using a function to set the style +@usage-- Using the function method to set the style +-- Use this method if your style is dynamic and depends on other factors local example_button = Gui.element{ type = 'button', - caption = 'Example Button' + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here } :style(function(style,element,...) + -- style is the current style object for the elemenent + -- element is the element that is being changed + -- ... shows that all other arguments from the factory call are passed to this function local player = game.players[element.player_index] style.height = 25 style.width = 100 @@ -226,12 +286,12 @@ function Gui._prototype_element:style(style_define) return self end ---[[-- Set the handler to be called on a custom event, only one handler can be used -@tparam string event_name the name of the event you want to handler to be called on +--[[-- Set the handler which will be called for a custom event, only one handler can be used per event per element +@tparam string event_name the name of the event you want to handler to be called on, often from Gui.events @tparam function handler the handler that you want to be called when the event is raised @treturn table the element define so more handleres can be registered -@usage Print the player name when my_custom_event is raised +@usage-- Register a handler to "my_custom_event" for this element element_deinfe:on_custom_event('my_custom_event', function(event) event.player.print(player.name) end) @@ -244,8 +304,8 @@ function Gui._prototype_element:on_custom_event(event_name,handler) return self end ---[[-- Raise the handler which is attached to any event; external use should be limited to custom events -@tparam table event the event table bassed to the handler, must include fields: name, element +--[[-- Raise the handler which is attached to an event; external use should be limited to custom events +@tparam table event the event table passed to the handler, must contain fields: name, element @treturn table the element define so more events can be raised @usage Raising a custom event @@ -283,7 +343,7 @@ function Gui._prototype_element:raise_custom_event(event) return self end --- This function is used to register a link between element define events and the events in the factorio api +-- This function is used to link element define events and the events from the factorio api local function event_handler_factory(event_name) Event.add(event_name, function(event) local element = event.element @@ -350,11 +410,5 @@ Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on -- @tparam function handler the event handler which will be called Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) ---- Custom element events. --- @section customEvents - --- Triggered when a user changed the visibility of a left flow element by clicking a button -Gui.events.on_visibility_changed_by_click = 'on_visibility_changed_by_click' - -- Module return return Gui \ No newline at end of file diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua index f4d5de9f..d9291d0f 100644 --- a/expcore/gui/top_flow.lua +++ b/expcore/gui/top_flow.lua @@ -1,5 +1,5 @@ --[[-- Core Module - Gui -- Used to define new gui elements and gui event handlers +- Controls the elements on the top flow @module Gui ]] @@ -12,7 +12,7 @@ local show_top_flow = Gui.core_defines.show_top_flow.name --- Top Flow. -- @section topFlow ---- Contains the uids of the elements that will show on the top flow and the auth function +--- Contains the uids of the elements that will shown on the top flow and their auth functions -- @table top_elements Gui.top_elements = {} @@ -20,29 +20,30 @@ Gui.top_elements = {} -- @field Gui.top_flow_button_style Gui.top_flow_button_style = mod_gui.button_style ---- The style that should be used for buttons on the top flow where the flow it opens is visible +--- The style that should be used for buttons on the top flow when their flow is visible -- @field Gui.top_flow_button_visible_style Gui.top_flow_button_visible_style = 'menu_button_continue' ---[[-- Gets the flow which contains the elements for the top flow +--[[-- Gets the flow refered to as the top flow, each player has one top flow @function Gui.get_top_flow(player) @tparam LuaPlayer player the player that you want to get the flow for @treturn LuaGuiElement the top element flow -@usage-- Geting your top element flow +@usage-- Geting your top flow local top_flow = Gui.get_top_flow(game.player) ]] Gui.get_top_flow = mod_gui.get_button_flow ---[[-- Adds an element to be drawn to the top flow when a player joins -@tparam[opt] function authenticator called during toggle or update to decide if the element should be visible -@treturn table the new element define that is used to register events to this element +--[[-- Sets an element define to be drawn to the top flow when a player joins, includes optional authenticator +@tparam[opt] function authenticator called during toggle or update to decide weather the element should be visible +@treturn table the new element define to allow event handlers to be registered -@usage-- Adding the example button +@usage-- Adding an element to the top flow on join example_button:add_to_top_flow(function(player) - -- example button will only show when game time is less than 1 minute - return player.online_time < 3600 + -- example button will only be shown if the player is an admin + -- note button will not update its state when player.admin is changed Gui.update_top_flow must be called for this + return player.admin end) ]] @@ -51,10 +52,10 @@ function Gui._prototype_element:add_to_top_flow(authenticator) return self end ---[[-- Updates the visible states of all the elements on a players top flow -@tparam LuaPlayer player the player that you want to update the flow for +--[[-- Updates the visible state of all the elements on the players top flow, uses authenticator +@tparam LuaPlayer player the player that you want to update the top flow for -@usage-- Update your flow +@usage-- Update your top flow Gui.update_top_flow(game.player) ]] @@ -64,7 +65,7 @@ function Gui.update_top_flow(player) local is_visible = hide_button.visible -- Set the visible state of all elements in the flow - for name,authenticator in pairs(Gui.top_elements) do + for name, authenticator in pairs(Gui.top_elements) do -- Ensure the element exists local element = top_flow[name] if not element then @@ -76,9 +77,9 @@ function Gui.update_top_flow(player) end end ---[[-- Toggles the visible states of all the elements on a players top flow -@tparam LuaPlayer player the player that you want to toggle the flow for -@tparam[opt] boolean state if given then the state will be set to this state +--[[-- Toggles the visible state of all the elements on a players top flow, effects all elements +@tparam LuaPlayer player the player that you want to toggle the top flow for +@tparam[opt] boolean state if given then the state will be set to this @treturn boolean the new visible state of the top flow @usage-- Toggle your flow diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 13bb1c7c..8cf23eef 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -105,7 +105,7 @@ Gui.element(function(event_trigger,parent,player_data) player_name.style.font_color = player_data.chat_color -- Add the time played label - local alignment = Gui.alignment(parent,nil,nil,'player-time-'..player_data.index) + local alignment = Gui.alignment(parent,'player-time-'..player_data.index) local time_label = alignment.add{ name = 'label', type = 'label', diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index b2490ed3..cc904c87 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -55,7 +55,7 @@ Gui.element(function(_,parent,label_data) name_label.style.padding = {0,2} --- Right aligned label to store the data - local alignment = Gui.alignment(parent,nil,nil,data_fullname) + local alignment = Gui.alignment(parent,data_fullname) local element = alignment.add{ type = 'label', @@ -302,7 +302,7 @@ Gui.element(function(_,parent,silo_data) silo_cords(parent,silo_data) -- Add a progress label - local alignment = Gui.alignment(parent,nil,nil,silo_name) + local alignment = Gui.alignment(parent,silo_name) local element = alignment.add{ type = 'label', diff --git a/modules/gui/science-info.lua b/modules/gui/science-info.lua index 0fd224fb..36d4d947 100644 --- a/modules/gui/science-info.lua +++ b/modules/gui/science-info.lua @@ -23,7 +23,7 @@ Gui.element(function(_,parent,production_label_data) local color = production_label_data.color -- Add an alignment for the number - local alignment = Gui.alignment(parent,nil,nil,name) + local alignment = Gui.alignment(parent,name) -- Add the main value label local element = diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index b1ef31e4..372555cf 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -118,7 +118,7 @@ Gui.element(function(_,parent,task_id) task_flow.style.padding = 0 -- Add the two edit buttons outside the task flow - local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..task_id) + local edit_flow = Gui.alignment(parent,'edit-'..task_id) edit_task(edit_flow) discard_task(edit_flow) diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 595a3ba2..1bf8b95b 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -137,7 +137,7 @@ Gui.element(function(_,parent,warp_id) warp_flow.style.padding = 0 -- Add the two edit buttons outside the warp flow - local edit_flow = Gui.alignment(parent,nil,nil,'edit-'..warp_id) + local edit_flow = Gui.alignment(parent,'edit-'..warp_id) edit_warp(edit_flow) discard_warp(edit_flow) From 60467a71909a808b1b0690c0acc8f73281852cbe Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 18 Mar 2020 21:19:54 +0000 Subject: [PATCH 40/81] Cleaned gui modules --- expcore/gui/left_flow.lua | 1 + modules/gui/player-list.lua | 8 +- modules/gui/rocket-info.lua | 293 ++++++++++++++++++------------------ modules/gui/task-list.lua | 2 +- modules/gui/warp-list.lua | 3 +- 5 files changed, 155 insertions(+), 152 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index cbe83bfa..f41d8419 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -178,6 +178,7 @@ function Gui.update_left_flow(player) return true end end + hide_button.visible = false return false end diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 8cf23eef..0c460eb7 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -1,5 +1,5 @@ --[[-- Gui Module - Player List - - Adds a player list to show names and play time; also includes action buttons which can apply to players + - Adds a player list to show names and play time; also includes action buttons which can preform actions to players @gui Player-List @alias player_list ]] @@ -60,7 +60,7 @@ Gui.element{ style = 'shortcut_bar_button_red' } :style(Gui.sprite_style(30,-1,{ top_margin = -1, right_margin = -1 })) -:on_click(function(player,element) +:on_click(function(player,_) Store.clear(selected_player_store,player) Store.clear(selected_action_store,player) end) @@ -170,7 +170,7 @@ Gui.element(function(_,parent) end) --- Updates the visible state of the action bar buttons -local function update_action_bar_buttons(element) +local function update_action_bar(element) local player = Gui.get_player_from_element(element) local selected_player_name = Store.get(selected_player_store,player) @@ -389,7 +389,7 @@ Store.watch(selected_player_store,function(value,player_name) local player = Game.get_player_from_any(player_name) local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table - update_action_bar_buttons(frame.container.action_bar) + update_action_bar(frame.container.action_bar) for _,next_player in pairs(game.connected_players) do local element = scroll_table[next_player.name][open_action_bar.name] local style = 'frame_button' diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index cc904c87..f2384a21 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -37,151 +37,6 @@ local function check_player_permissions(player,action) return true end ---- Data label which contains a name and a value label pair --- @element data_label -local data_label = -Gui.element(function(_,parent,label_data) - local data_name = label_data.name - local data_subname = label_data.subname - local data_fullname = data_subname and data_name..data_subname or data_name - - -- Add the name label - local name_label = parent.add{ - type = 'label', - name = data_fullname..'-label', - caption = {'rocket-info.data-caption-'..data_name,data_subname}, - tooltip = {'rocket-info.data-tooltip-'..data_name,data_subname} - } - name_label.style.padding = {0,2} - - --- Right aligned label to store the data - local alignment = Gui.alignment(parent,data_fullname) - local element = - alignment.add{ - type = 'label', - name = 'label', - caption = label_data.value, - tooltip = label_data.tooltip - } - element.style.padding = {0,2} - - return element -end) - -local function update_data_labels(parent,data_label_data) - for _, label_data in ipairs(data_label_data) do - local data_name = label_data.subname and label_data.name..label_data.subname or label_data.name - if not parent[data_name] then - data_label(parent,label_data) - else - local data_label_element = parent[data_name].label - data_label_element.tooltip = label_data.tooltip - data_label_element.caption = label_data.value - end - end -end - ---- Gets the label data for all the different stats -local function get_stats_data(force_name) - local force_rockets = Rockets.get_rocket_count(force_name) - local stats = Rockets.get_stats(force_name) - local stats_data = {} - - -- Format the first launch data - if config.stats.show_first_rocket then - local value = stats.first_launch or 0 - table.insert(stats_data,{ - name = 'first-launch', - value = time_formats.caption_hours(value), - tooltip = time_formats.tooltip_hours(value) - }) - end - - -- Format the last launch data - if config.stats.show_last_rocket then - local value = stats.last_launch or 0 - table.insert(stats_data,{ - name = 'last-launch', - value = time_formats.caption_hours(value), - tooltip = time_formats.tooltip_hours(value) - }) - end - - -- Format fastest launch data - if config.stats.show_fastest_rocket then - local value = stats.fastest_launch or 0 - table.insert(stats_data,{ - name = 'fastest-launch', - value = time_formats.caption_hours(value), - tooltip = time_formats.tooltip_hours(value) - }) - end - - -- Format total rocket data - if config.stats.show_total_rockets then - local total_rockets = Rockets.get_game_rocket_count() - total_rockets = total_rockets == 0 and 1 or total_rockets - local percentage = math.round(force_rockets/total_rockets,3)*100 - table.insert(stats_data,{ - name = 'total-rockets', - value = force_rockets, - tooltip = {'rocket-info.value-tooltip-total-rockets',percentage} - }) - end - - -- Format game avg data - if config.stats.show_game_avg then - local avg = force_rockets > 0 and math.floor(game.tick/force_rockets) or 0 - table.insert(stats_data,{ - name = 'avg-launch', - value = time_formats.caption(avg), - tooltip = time_formats.tooltip(avg) - }) - end - - -- Format rolling avg data - for _,avg_over in pairs(config.stats.rolling_avg) do - local avg = Rockets.get_rolling_average(force_name,avg_over) - table.insert(stats_data,{ - name = 'avg-launch-n', - subname = avg_over, - value = time_formats.caption(avg), - tooltip = time_formats.tooltip(avg) - }) - end - - -- Return formated data - return stats_data -end - ---- Gets the label data for the milestones -local function get_milestone_data(force_name) - local force_rockets = Rockets.get_rocket_count(force_name) - local milestone_data = {} - - for _,milestone in ipairs(config.milestones) do - if milestone <= force_rockets then - local time = Rockets.get_rocket_time(force_name,milestone) - table.insert(milestone_data,{ - name = 'milestone-n', - subname = milestone, - value = time_formats.caption_hours(time), - tooltip = time_formats.tooltip_hours(time) - }) - else - table.insert(milestone_data,{ - name = 'milestone-n', - subname = milestone, - value = {'rocket-info.data-caption-milestone-next'}, - tooltip = {'rocket-info.data-tooltip-milestone-next'} - }) - break - end - end - - return milestone_data -end - --- Button to toggle the auto launch on a rocket silo -- @elemeent toggle_launch local toggle_launch = @@ -191,7 +46,7 @@ Gui.element{ tooltip = {'rocket-info.toggle-rocket-tooltip'} } :style(Gui.sprite_style(16)) -:on_click(function(player,element,_) +:on_click(function(_,element,_) local rocket_silo_name = element.parent.name:sub(8) local rocket_silo = Rockets.get_silo_entity(rocket_silo_name) if rocket_silo.auto_launch then @@ -315,6 +170,51 @@ Gui.element(function(_,parent,silo_data) return element end) +--- Data label which contains a name and a value label pair +-- @element data_label +local data_label = +Gui.element(function(_,parent,label_data) + local data_name = label_data.name + local data_subname = label_data.subname + local data_fullname = data_subname and data_name..data_subname or data_name + + -- Add the name label + local name_label = parent.add{ + type = 'label', + name = data_fullname..'-label', + caption = {'rocket-info.data-caption-'..data_name,data_subname}, + tooltip = {'rocket-info.data-tooltip-'..data_name,data_subname} + } + name_label.style.padding = {0,2} + + --- Right aligned label to store the data + local alignment = Gui.alignment(parent,data_fullname) + local element = + alignment.add{ + type = 'label', + name = 'label', + caption = label_data.value, + tooltip = label_data.tooltip + } + element.style.padding = {0,2} + + return element +end) + +-- Used to update the captions and tooltips on the data labels +local function update_data_labels(parent,data_label_data) + for _, label_data in ipairs(data_label_data) do + local data_name = label_data.subname and label_data.name..label_data.subname or label_data.name + if not parent[data_name] then + data_label(parent,label_data) + else + local data_label_element = parent[data_name].label + data_label_element.tooltip = label_data.tooltip + data_label_element.caption = label_data.value + end + end +end + local function get_progress_data(force_name) local force_silos = Rockets.get_silos(force_name) local progress_data = {} @@ -417,6 +317,107 @@ local function update_build_progress(parent,progress_data) if show_message then parent.no_silos.visible = true end end +--- Gets the label data for all the different stats +local function get_stats_data(force_name) + local force_rockets = Rockets.get_rocket_count(force_name) + local stats = Rockets.get_stats(force_name) + local stats_data = {} + + -- Format the first launch data + if config.stats.show_first_rocket then + local value = stats.first_launch or 0 + table.insert(stats_data,{ + name = 'first-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format the last launch data + if config.stats.show_last_rocket then + local value = stats.last_launch or 0 + table.insert(stats_data,{ + name = 'last-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format fastest launch data + if config.stats.show_fastest_rocket then + local value = stats.fastest_launch or 0 + table.insert(stats_data,{ + name = 'fastest-launch', + value = time_formats.caption_hours(value), + tooltip = time_formats.tooltip_hours(value) + }) + end + + -- Format total rocket data + if config.stats.show_total_rockets then + local total_rockets = Rockets.get_game_rocket_count() + total_rockets = total_rockets == 0 and 1 or total_rockets + local percentage = math.round(force_rockets/total_rockets,3)*100 + table.insert(stats_data,{ + name = 'total-rockets', + value = force_rockets, + tooltip = {'rocket-info.value-tooltip-total-rockets',percentage} + }) + end + + -- Format game avg data + if config.stats.show_game_avg then + local avg = force_rockets > 0 and math.floor(game.tick/force_rockets) or 0 + table.insert(stats_data,{ + name = 'avg-launch', + value = time_formats.caption(avg), + tooltip = time_formats.tooltip(avg) + }) + end + + -- Format rolling avg data + for _,avg_over in pairs(config.stats.rolling_avg) do + local avg = Rockets.get_rolling_average(force_name,avg_over) + table.insert(stats_data,{ + name = 'avg-launch-n', + subname = avg_over, + value = time_formats.caption(avg), + tooltip = time_formats.tooltip(avg) + }) + end + + -- Return formated data + return stats_data +end + +--- Gets the label data for the milestones +local function get_milestone_data(force_name) + local force_rockets = Rockets.get_rocket_count(force_name) + local milestone_data = {} + + for _,milestone in ipairs(config.milestones) do + if milestone <= force_rockets then + local time = Rockets.get_rocket_time(force_name,milestone) + table.insert(milestone_data,{ + name = 'milestone-n', + subname = milestone, + value = time_formats.caption_hours(time), + tooltip = time_formats.tooltip_hours(time) + }) + else + table.insert(milestone_data,{ + name = 'milestone-n', + subname = milestone, + value = {'rocket-info.data-caption-milestone-next'}, + tooltip = {'rocket-info.data-tooltip-milestone-next'} + }) + break + end + end + + return milestone_data +end + -- Button to toggle a section dropdown -- @element toggle_section local toggle_section = diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index 372555cf..b8b260b0 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -1,5 +1,5 @@ --[[-- Gui Module - Task List - - Adds a task list to the game which players can add remove and edit items on + - Adds a task list to the game which players can add, remove and edit items on @gui Task-List @alias task_list ]] diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 1bf8b95b..de92d42e 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -79,7 +79,7 @@ Gui.element{ style = 'tool_button' } :style(Styles.sprite20) -:on_click(function(player,element) +:on_click(function(player,_) -- Add the new warp local force_name = player.force.name local surface = player.surface @@ -263,6 +263,7 @@ Gui.element(function(event_trigger,parent,warp) end) :style(Styles.sprite32) :on_click(function(player,element,_) + if element.type == 'choose-elem-button' then return end local warp_id = element.parent.caption Warps.teleport_player(warp_id,player) From a2dec8f16ca50f4f874123a7d491f917369c59eb Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 18 Mar 2020 21:37:29 +0000 Subject: [PATCH 41/81] Removed unused config value --- config/roles.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config/roles.lua b/config/roles.lua index 8bc10b92..603191b6 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -217,9 +217,7 @@ local default = Roles.new_role('Guest','') 'gui/rocket-info', 'gui/science-info', 'gui/task-list', - 'gui/warp-list', - 'gui/warp-list/apply-cooldown', - 'gui/warp-list/apply-proximity', + 'gui/warp-list' } --- Jail role From fc79cedf5b3a662f50289fe6d8cb3aeb6154e49c Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 21 Mar 2020 13:23:17 +0000 Subject: [PATCH 42/81] Added Custom Join Messages --- config/join_messages.lua | 3 +++ modules/addons/greetings.lua | 25 ++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 config/join_messages.lua diff --git a/config/join_messages.lua b/config/join_messages.lua new file mode 100644 index 00000000..866ac6e8 --- /dev/null +++ b/config/join_messages.lua @@ -0,0 +1,3 @@ +return { + ['Cooldude2606'] = 'Lua lets you set metatables on numbers, did you know that? Cooldude2606 knows this.' +} \ No newline at end of file diff --git a/modules/addons/greetings.lua b/modules/addons/greetings.lua index 28c3766a..df625656 100644 --- a/modules/addons/greetings.lua +++ b/modules/addons/greetings.lua @@ -1,14 +1,25 @@ --greets players on join local Event = require 'utils.event' --- @dep utils.event -local greet = -function(event) - local message = {'greetings.greet',{'links.discord'}} - game.players[event.player_index].print(message) +local Game = require 'utils.game' --- @dep utils.event +local config = require 'config.join_messages' --- @dep config.join_messages +local Global = require 'utils.global' --- @dep utils.global +require 'utils.table' +Global.register(config,function(tbl) + config = tbl +end) + +local greet = +function(event) + local player = Game.get_player_by_index(event.player_index) + local custom_message = config[player.name] + if custom_message then + game.print(custom_message,player.color) + else + player.print{'greetings.greet',{'links.discord'}} + end end - - -Event.add(defines.events.on_player_joined_game ,greet) \ No newline at end of file +Event.add(defines.events.on_player_joined_game, greet) \ No newline at end of file From 63c683e8d1818885b778505abc4e1ea20c6fce67 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 22 Mar 2020 20:29:08 +0000 Subject: [PATCH 43/81] Added some custom join messages --- config/join_messages.lua | 5 ++++- config/preset_player_colours.lua | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config/join_messages.lua b/config/join_messages.lua index 866ac6e8..0fdea603 100644 --- a/config/join_messages.lua +++ b/config/join_messages.lua @@ -1,3 +1,6 @@ return { - ['Cooldude2606'] = 'Lua lets you set metatables on numbers, did you know that? Cooldude2606 knows this.' + Cooldude2606 = 'Lua lets you set metatables on numbers, did you know that? Cooldude2606 knows this.', + samy115 = 'Tremble in fear as the banhammer is now here, its owner: samy115', + XenoCyber = '"Fire :fire: Fire :fire: Fire" oops wrong game, have no fear XenoCyber is here', + HunterOfGames = 'Unable to support HunterOfGames. You must construct additional miners.' } \ No newline at end of file diff --git a/config/preset_player_colours.lua b/config/preset_player_colours.lua index d186fa01..b7e0bde7 100644 --- a/config/preset_player_colours.lua +++ b/config/preset_player_colours.lua @@ -16,7 +16,10 @@ return { UUBlueFire={r=0,g=204,b=255}, CmonMate497={r=103,g=224,b=194}, s4sh={r=255,g=120,b=0}, - ArPiiX={r=0,g=255,b=0} + ArPiiX={r=0,g=255,b=0}, + NextIdea={r=255,g=255,b=255}, + hamsterbryan={r=0,g=255,b=0}, + XenoCyber={r=0,g=128,b=255} }, disallow = { --- @setting disallow colours which will not given to players; the value does not matter it is only the key which is checked black = {r = 0, g = 0, b = 0}, From a6a500cf03a8b68c73c68bd464eef462bef82259 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 22 Mar 2020 21:55:01 +0000 Subject: [PATCH 44/81] Removed failed emotes --- config/join_messages.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/join_messages.lua b/config/join_messages.lua index 0fdea603..058435d3 100644 --- a/config/join_messages.lua +++ b/config/join_messages.lua @@ -1,6 +1,6 @@ return { Cooldude2606 = 'Lua lets you set metatables on numbers, did you know that? Cooldude2606 knows this.', samy115 = 'Tremble in fear as the banhammer is now here, its owner: samy115', - XenoCyber = '"Fire :fire: Fire :fire: Fire" oops wrong game, have no fear XenoCyber is here', + XenoCyber = '"Fire Fire Fire" oops wrong game, have no fear XenoCyber is here', HunterOfGames = 'Unable to support HunterOfGames. You must construct additional miners.' } \ No newline at end of file From f4eb5ada5abb01da86f2283fa24803de590446aa Mon Sep 17 00:00:00 2001 From: badgamernl Date: Sun, 22 Mar 2020 22:56:39 +0100 Subject: [PATCH 45/81] Fix async module to allow recursive "async" functions Return `true` in async function to run again --- expcore/async.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expcore/async.lua b/expcore/async.lua index 21ae7080..a988563b 100644 --- a/expcore/async.lua +++ b/expcore/async.lua @@ -36,7 +36,7 @@ local Async = {} local internal_run = Token.register(function(params) local func = Token.get(params.token) - func(unpack(params.params)) + return func(unpack(params.params)) end) --- Register a new async function, must called when the file is loaded From 3a0897e569139aa6d7097433be9c09bbaa5c594f Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 22 Mar 2020 22:30:34 +0000 Subject: [PATCH 46/81] Updated Factorio Lua Check --- .gitignore | 5 +- .luacheckrc | 2557 +++++++++++++++++++++++++++---------------- Factorio-luacheckrc | 2 +- 3 files changed, 1628 insertions(+), 936 deletions(-) diff --git a/.gitignore b/.gitignore index 9a140dc8..b23b7166 100644 --- a/.gitignore +++ b/.gitignore @@ -82,7 +82,4 @@ $RECYCLE.BIN/ *.msp # Windows shortcuts -*.lnk - -.vscode -*luacheckrc +*.lnk \ No newline at end of file diff --git a/.luacheckrc b/.luacheckrc index c3e0c5cf..98d8fa3e 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1,947 +1,1641 @@ -------------------------------------------------------------------------------- ---[LICENSE]-- -------------------------------------------------------------------------------- --- .luacheckrc --- This file is free and unencumbered software released into the public domain. --- --- Anyone is free to copy, modify, publish, use, compile, sell, or --- distribute this file, either in source code form or as a compiled --- binary, for any purpose, commercial or non-commercial, and by any --- means. --- --- In jurisdictions that recognize copyright laws, the author or authors --- of this file dedicate any and all copyright interest in the --- software to the public domain. We make this dedication for the benefit --- of the public at large and to the detriment of our heirs and --- successors. We intend this dedication to be an overt act of --- relinquishment in perpetuity of all present and future rights to this --- software under copyright law. --- --- THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, --- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF --- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. --- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR --- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, --- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR --- OTHER DEALINGS IN THE SOFTWARE. --- --- For more information, please refer to --- ]] +--[[---------------------------------------------------------------------------- + LICENSE + .luacheckrc for Factorio Version 0.18.8, luacheck version 0.23.0 + This file is free and unencumbered software released into the public domain. -------------------------------------------------------------------------------- ---[.luacheckrc]-- Current Factorio Version .16 -------------------------------------------------------------------------------- --- Set up the the standards for this file. -files['.luacheckrc'] = { - std = 'lua52c', - globals = {'files', 'exclude_files', 'not_globals', 'stds', 'std', 'max_line_length', 'ignore', 'quiet', "max_cyclomatic_complexity", "codes"}, - max_line_length = false --turn of line length warnings for this file -} + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this file, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this file dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to +------------------------------------------------------------------------------]] +local LINE_LENGTH = false -------------------------------------------------------------------------------- ---[Set Defaults]-- -------------------------------------------------------------------------------- -local LINE_LENGTH = false -- It is 2017 limits on length are a waste local IGNORE = {'21./%w+_$', '21./^_%w+$', '213/[ijk]', '213/index', '213/key'} -local NOT_GLOBALS = {'coroutine', 'io', 'socket', 'dofile', 'loadfile'} -- These globals are not available to the factorio API -local STD_CONTROL = 'lua52c+factorio+factorio_control+stdlib+factorio_defines' -local STD_DATA = 'lua52c+factorio+factorio_data+stdlib+stdlib_data+factorio_defines' +-- These globals are not available to the factorio API +local NOT_GLOBALS = {'coroutine', 'io', 'socket', 'dofile', 'loadfile'} --- In a perfect world these would be STD_DATA and STD_CONTROL (mostly) -local STD_BASE_DATA = 'lua52c+factorio+factorio_data+factorio_defines+factorio_base_data' -local STD_BASE_CONTROL = 'lua52c+factorio+factorio_control+factorio_defines+factorio_base_control' +local STD_CONTROL = 'lua52+factorio+factorio_control+stdlib+factorio_defines' +local STD_DATA = 'lua52+factorio+factorio_data+stdlib+stdlib_data+factorio_defines' -------------------------------------------------------------------------------- ---[Assume Factorio Control stage as default]-- -------------------------------------------------------------------------------- -std = STD_CONTROL -max_line_length = LINE_LENGTH +-- For Base and Core Mods +local STD_BASE_DATA = 'lua52+factorio+factorio_data+factorio_defines+factorio_base_data' +local STD_BASE_CONTROL = 'lua52+factorio+factorio_control+factorio_defines+factorio_base_control' -not_globals = NOT_GLOBALS -ignore = IGNORE -quiet = 1 -- pass -q option -max_cyclomatic_complexity = 75 -codes = true - ---List of files and directories to exclude -exclude_files = { - --Ignore special folders - '**/.*/*', --Ignore if path starts with . - '**/mod/stdlib/', --Ignore from symlinked - '**/vendor/', - - --Ignore development mods - '**/combat-tester/', - '**/test-maker/', - '**/trailer/', -} - -------------------------------------------------------------------------------- ---[Mod Prototypes]-- -------------------------------------------------------------------------------- ---Set default prototype files -files['**/data.lua'].std = STD_DATA -files['**/data-updates.lua'].std = STD_DATA -files['**/data-final-fixes.lua'].std = STD_DATA -files['**/settings.lua'].std = STD_DATA -files['**/settings-updates.lua'].std = STD_DATA -files['**/settings-final-fixes.lua'].std = STD_DATA -files['**/prototypes/'].std = STD_DATA -files['**/settings/'].std = STD_DATA - -------------------------------------------------------------------------------- ---[Base]-- -------------------------------------------------------------------------------- ---Find and replace ignores *.cfg, migrations, *.txt, control.lua, *.json, trailer, scenarios, campaigns, *.glsl - -local base_scenarios = { - std = STD_BASE_CONTROL .. '+factorio_base_scenarios+factorio_base_story', - --Ignore these, Klonan is on his own! - --ignore = {'212/event', '111', '112', '113', '211', '212', '213', '311', '411', '412', '421', '422', '423', '431', '432', '512'} - ignore = {'...'} -} -files['**/base/scenarios/'] = base_scenarios -files['**/base/tutorials/'] = base_scenarios -files['**/base/campaigns/'] = base_scenarios -files['**/wip-scenario/'] = base_scenarios - -files['**/base/migrations/'] = {std = STD_BASE_CONTROL} - -files['**/core/lualib/'] = {std = STD_BASE_CONTROL} -files['**/core/lualib/util.lua'] = {globals = {'util', 'table'}, ignore = {'432/object'}} -files['**/core/lualib/silo-script.lua'] = {globals = {'silo_script'}, ignore = {'4../player'}} -files['**/core/lualib/production-score.lua'] = {globals = {'production_score', 'get_price_recursive'}, ignore = {'4../player'}} -files['**/core/lualib/story*'] = {std = '+factorio_base_story', ignore = {'42./k', '42./filter'}} -files['**/core/lualib/mod-gui.lua'] = {globals = {'mod_gui'}} -files['**/core/lualib/camera.lua'] = {globals = {'camera'}} -files['**/core/lualib/builder.lua'] = {globals = {'Builder', 'builder', 'action', 'down', 'right'}} - -files['**/core/lualib/bonus-gui-ordering/'] = {std = STD_BASE_DATA} -files['**/core/lualib/dataloader.lua'] = {globals = {'data'}} -files['**/core/lualib/circuit-connector-*'] = {std = STD_BASE_DATA..'+factorio_circuit_connector_generated'} -files['**/core/lualib/bonus-gui-ordering.lua'] = {globals = {'bonus_gui_ordering'}} - -files['**/base/prototypes/'] = {std = STD_BASE_DATA} -files['**/core/prototypes/'] = {std = STD_BASE_DATA} -files['**/core/prototypes/noise-programs.lua'] = {ignore = {'212/x', '212/y', '212/tile', '212/map'}} - -------------------------------------------------------------------------------- ---[Set STDLIB project modules]-- -------------------------------------------------------------------------------- -local stdlib_control = { - std = 'lua52c+factorio+factorio_control+stdlib+factorio_defines', +do -- Assume Factorio Control Stage as Default + std = STD_CONTROL + --cache = true + not_globals = NOT_GLOBALS + ignore = IGNORE + quiet = 1 -- pass -q option + max_cyclomatic_complexity = false + codes = true max_line_length = LINE_LENGTH -} + max_code_line_length = LINE_LENGTH + max_string_line_length = LINE_LENGTH + max_comment_line_length = LINE_LENGTH -local stdlib_data = { - std = 'lua52c+factorio+factorio_data+stdlib+factorio_defines', - max_line_length = LINE_LENGTH -} + --List of files and directories to exclude + exclude_files = { + --Ignore special folders + '**/.trash/', + '**/.history/', + '**/stdlib/vendor/', --- Assume control stage for stdlib -files['**/stdlib/'] = stdlib_control + --Ignore development mods + '**/combat-tester/', + '**/test-maker/', + '**/trailer/', -files['**/stdlib/utils/math.lua'].std = 'lua52c' -files['**/stdlib/utils/string.lua'].std = 'lua52c' -files['**/stdlib/utils/table.lua'].std = 'lua52c' -files['**/stdlib/utils/iterator.lua'].std = 'lua52c' -files['**/stdlib/utils/is.lua'].std = 'lua52c' + --Ignore love Includes + '**/love/includes/' + } +end --- STDLIB data files -files['**/stdlib/data/'] = stdlib_data -files['**/creative'].ignore = {'...'} +do -- Set default prototype files + files['**/data.lua'].std = STD_DATA + files['**/data-updates.lua'].std = STD_DATA + files['**/data-final-fixes.lua'].std = STD_DATA + files['**/settings.lua'].std = STD_DATA + files['**/settings-updates.lua'].std = STD_DATA + files['**/settings-final-fixes.lua'].std = STD_DATA + files['**/prototypes/'].std = STD_DATA + files['**/settings/'].std = STD_DATA +end --- STDLIB Busted Spec -files['**/spec/**'] = { - globals = {'serpent', 'log', 'SLOG', 'RESET'}, - std = 'lua52c+busted+factorio_defines+factorio_control+stdlib' -} +do -- Base and Core mod files + local base_scenarios = { + std = STD_BASE_CONTROL .. '+factorio_base_scenarios+factorio_base_story', + --ignore = {'212/event', '111', '112', '113', '211', '212', '213', '311', '411', '412', '421', '422', '423', '431', '432', '512'} + ignore = {'...'} + } + files['**/base/scenarios/'] = base_scenarios + files['**/base/tutorials/'] = base_scenarios + files['**/base/campaigns/'] = base_scenarios + files['**/wip-scenario/'] = base_scenarios + files['**/base/migrations/'] = {std = STD_BASE_CONTROL} -------------------------------------------------------------------------------- ---[STDS FACTORIO]-- -------------------------------------------------------------------------------- -stds.factorio = { - --Set the read only variables - read_globals = { - -- @log@: Gives writing access to Factorio's logger instance. - "log", - -- @serpent@: Lua serializer and pretty printer. (https://github.com/pkulchenko/serpent) - "serpent", - -- @table_size@: Returns the number of elements inside an LUA table - "table_size", - util = { - fields = { - "by_pixel", "distance", "findfirstentity", "positiontostr", "formattime", "moveposition", "oppositedirection", - "ismoduleavailable", "multiplystripes", "format_number", "increment", "color", "conditional_return", - "add_shift", "merge", "premul_color", "encode", "decode", - table = { - fields = { - "compare", "deepcopy" + files['**/core/lualib/'] = {std = STD_BASE_CONTROL} + files['**/core/lualib/util.lua'] = {globals = {'util', 'table'}, ignore = {'432/object'}} + files['**/core/lualib/silo-script.lua'] = {globals = {'silo_script'}, ignore = {'4../player'}} + files['**/core/lualib/production-score.lua'] = {globals = {'production_score', 'get_price_recursive'}, ignore = {'4../player'}} + files['**/core/lualib/story*'] = {std = '+factorio_base_story', ignore = {'42./k', '42./filter'}} + files['**/core/lualib/mod-gui.lua'] = {globals = {'mod_gui'}} + files['**/core/lualib/camera.lua'] = {globals = {'camera'}} + files['**/core/lualib/builder.lua'] = {globals = {'Builder', 'builder', 'action', 'down', 'right'}} + + files['**/core/lualib/bonus-gui-ordering/'] = {std = STD_BASE_DATA} + files['**/core/lualib/dataloader.lua'] = {globals = {'data'}} + files['**/core/lualib/circuit-connector-*'] = {std = STD_BASE_DATA..'+factorio_circuit_connector_generated'} + files['**/core/lualib/bonus-gui-ordering.lua'] = {globals = {'bonus_gui_ordering'}} + + files['**/base/prototypes/'] = {std = STD_BASE_DATA} + files['**/core/prototypes/'] = {std = STD_BASE_DATA} + files['**/core/prototypes/noise-programs.lua'] = {ignore = {'212/x', '212/y', '212/tile', '212/map'}} +end + +do -- Stdlib Files + local stdlib_control = { + std = 'lua52+factorio+factorio_control+stdlib+factorio_defines', + max_line_length = LINE_LENGTH + } + + local stdlib_data = { + std = 'lua52+factorio+factorio_data+stdlib+factorio_defines', + max_line_length = LINE_LENGTH + } + + -- Assume control stage for stdlib + files['**/stdlib/'] = stdlib_control + + -- Assume generic lua for stdlib utils + files['**/stdlib/utils/**'].std = 'lua52+stdlib' + + -- STDLIB data stage files + files['**/stdlib/data/'] = stdlib_data + + -- STDLIB Busted Spec + files['**/spec/**'] = { + globals = {'serpent', 'log', 'package.remove_stdlib'}, + std = 'lua52c+busted+factorio_defines+factorio_control+stdlib' + } + + -- Love + files['**/love/'].std = 'luajit+love+love_extra+stdlib+stdlib_data' +end + +do -- Factorio STDs-- + stds.factorio = { + --Set the read only variables + read_globals = { + -- @log@: Gives writing access to Factorio's logger instance. + "log", + -- @serpent@: Lua serializer and pretty printer. (https://github.com/pkulchenko/serpent). + "serpent", + -- @table_size@: Returns the number of elements inside an LUA table. + "table_size", + -- @lldebugger@: Provided by lua local debugger vscode extension. + lldebugger = { + fields = {'requestBreak'}, + other_fields = true, + read_only = false, + }, + -- @__DebugAdapter@: Provided by Factorio Mod Debug vscode extension. + __DebugAdapter = { + fields = {'print', 'stepIgnoreAll', 'stepIgnore', 'breakpoint'}, + other_fields = true, + read_only = false + }, + util = { + fields = { + "by_pixel", "distance", "findfirstentity", "positiontostr", "formattime", "moveposition", "oppositedirection", + "ismoduleavailable", "multiplystripes", "format_number", "increment", "color", "conditional_return", + "add_shift", "merge", "premul_color", "encode", "decode", "insert_safe", + table = { + fields = { + "compare", "deepcopy" + }, }, }, }, - }, - table = { - fields = { - "compare", "deepcopy" + table = { + fields = { + "compare", "deepcopy" + }, }, }, - }, -} + } -stds.factorio_control = { - read_globals = { + stds.factorio_control = { + read_globals = { - -- @commands@: - commands = { - fields = { - "add_command", "commands", "game_commands", "remove_command", + -- @commands@: + commands = { + fields = { + "add_command", "commands", "game_commands", "remove_command" + }, }, - }, - -- @settings@: - settings = { - fields = { - "get_player_settings", - startup = {read_only = false, other_fields = true}, - global = {read_only = false, other_fields = true}, - player = {read_only = false, other_fields = true}, + -- @settings@: + settings = { + fields = { + "get_player_settings", + startup = {other_fields = true}, + global = {other_fields = true}, + player = {other_fields = true}, + get = {read_only = false}, -- stdlib added + get_startup = {read_only = false} -- stdlib added + }, }, - }, - -- @script@: Provides an interface for registering event handlers. - -- (http://lua-api.factorio.com/latest/LuaBootstrap.html) - script = { - fields = { - "on_event", "on_nth_tick", "on_configuration_changed", "on_init", "on_load", "generate_event_name", - "raise_event", "get_event_handler", "mod_name", "get_event_order" + -- @script@: Provides an interface for registering event handlers. + -- (http://lua-api.factorio.com/latest/LuaBootstrap.html) + script = { + fields = { + "on_event", "on_nth_tick", "on_configuration_changed", "on_init", "on_load", "generate_event_name", + "raise_event", "get_event_handler", "mod_name", "get_event_order", + "is_game_in_debug_mode", "object_name", "set_event_filter", "get_event_filter", + active_mods = {read_only = true, other_fields = true}, + }, + other_fields = false, }, - }, - -- @remote@: Allows inter-mod communication by providing a repository of interfaces that is shared by all mods. - -- (http://lua-api.factorio.com/latest/LuaRemote.html) - remote = { - fields = { - "add_interface", "remove_interface", "call", "interfaces" + -- @remote@: Allows inter-mod communication by providing a repository of interfaces that is shared by all mods. + -- (http://lua-api.factorio.com/latest/LuaRemote.html) + remote = { + fields = { + interfaces = {read_only = false, other_fields = true}, + "add_interface", "remove_interface", "call" + }, + read_only = true, + other_fields = false, }, - }, - -- @game@: Main object through which most of the API is accessed. - -- It is, however, not available inside handlers registered with @script.on_load@. - -- (http://lua-api.factorio.com/latest/LuaGameScript.html) - game ={ - other_fields = true, - read_only = false, - fields = { - "set_game_state", "get_entity_by_tag", "show_message_dialog", "disable_tips_and_tricks", "is_demo", "reload_script", - "save_atlas", "check_consistency", "regenerate_entity", "take_screenshot", "write_file", "remove_path", - "remove_offline_players", "force_crc", "merge_forces", "player", "server_save", "delete_surface", "disable_replay", - "direction_to_string", "print", "tick", "finished", "difficulty", - speed = { - --rw - read_only = false, - }, - player = { - --luaPlayer - --The player typing at the console, nil in all other cases - read_only = false, - other_fields = true, - }, - players = { - --array of luaPlayer - read_only = false, - other_fields = true, - }, - connected_players = { - --array of luaPlayer - read_only = false, - other_fields = true, - }, - surfaces = { - --array of luaSurface - read_only = false, - other_fields = true, - }, - create_surface = { - --luaSurface - read_only = false, - other_fields = true, - }, - forces = { - --array of luaForce - read_only = false, - other_fields = true, - }, - create_force = { - --luaForce - read_only = false, - other_fields = true, - }, - entity_prototypes = { - --string dictionary - > luaEntityPrototype - read_only = true, - other_fields = true - }, - item_prototypes = { - --string dictionary - > luaItemPrototype - read_only = true, - other_fields = true - }, - fluid_prototypes = { - --string dictionary - > luaFluidPrototype - read_only = true, - other_fields = true - }, - tile_prototypes = { - --string dictionary - > luaTilePrototype - read_only = true, - other_fields = true - }, - equipment_prototypes = { - --string dictionary - > luaEquipmentPrototype - read_only = true, - other_fields = true - }, - recipe_prototypes = { - --string dictionary - > luaRecipePrototype - read_only = true, - other_fields = true - }, - technology_prototypes = { - --string dictionary - > luaTechnologyPrototype - read_only = true, - other_fields = true - }, - damage_prototypes = { - --string dictionary - > luaDamagePrototype - read_only = true, - other_fields = true - }, - virtual_signal_prototypes = { - --string dictionary - > luaVirtualSignalPrototype - read_only = true, - other_fields = true - }, - equipment_grid_prototypes = { - --string dictionary - > luaEquipmentGridPrototype - read_only = true, - other_fields = true - }, - decorative_prototypes = { - --string dictionary -> LuaDecorativePrototype - read_only = true, - other_fields = true - }, - map_settings = { - --custom -> mapsettings - read_only = false, - other_fields = true - }, - active_mods = { - --string dictionary -> string version - read_only = true, - other_fields = true - }, - permissions = { - read_only = true, - other_fields = true - }, - backer_names = { - read_only = true, - other_fields = true + rcon = { + fields = {'print'} + }, + + rendering = { + other_fields = false, + read_only = true, + fields = { + 'draw_animation', + 'draw_line', + 'draw_text', + 'draw_circle', + 'draw_rectangle', + 'draw_arc', + 'draw_polygon', + 'draw_sprite', + 'draw_light', + 'destroy', + 'is_font_valid', + 'is_valid', + 'get_all_ids', + 'clear', + 'get_type', + 'get_surface', + 'get_time_to_live', + 'set_time_to_live', + 'get_forces', + 'set_forces', + 'get_players', + 'set_players', + 'get_color', + 'set_color', + 'get_width', + 'set_width', + 'get_from', + 'set_from', + 'get_to', + 'set_to', + 'get_gap_amount', + 'set_gap_amount', + 'get_gap_length', + 'set_gap_length', + 'get_target', + 'set_target', + 'get_orientation', + 'set_orientation', + 'get_scale', + 'set_scale', + 'get_text', + 'set_text', + 'get_font', + 'set_font', + 'get_alignment', + 'set_alignment', + 'get_scale_with_zoom', + 'set_scale_with_zoom', + 'get_filled', + 'set_filled', + 'get_radius', + 'set_radius', + 'get_left_top', + 'set_left_top', + 'get_right_bottom', + 'set_right_bottom', + 'get_max_radius', + 'set_max_radius', + 'get_min_radius', + 'set_min_radius', + 'get_start_angle', + 'set_start_angle', + 'get_angle', + 'set_angle', + 'get_vertices', + 'set_vertices', + 'get_sprite', + 'set_sprite', + 'get_x_scale', + 'set_x_scale', + 'get_y_scale', + 'set_y_scale', + 'get_render_layer', + 'set_render_layer', + 'get_orientation_target', + 'set_orientation_target', + 'get_oriented_offset', + 'set_oriented_offset', + 'get_intensity', + 'set_intensity', + 'get_minimum_darkness', + 'set_minimum_darkness' } }, - }, - }, - globals = { - -- @global@: The global dictionary, useful for storing data persistent across a save-load cycle. - -- Writing access is given to the mod-id field (for mod-wise saved data). - -- (http://lua-api.factorio.com/latest/Global.html) - "global", + -- @game@: Main object through which most of the API is accessed. + -- It is, however, not available inside handlers registered with @script.on_load@. + -- (http://lua-api.factorio.com/latest/LuaGameScript.html) + game ={ + other_fields = false, + read_only = false, + fields = { + 'auto_save', + 'ban_player', + 'check_consistency', + 'check_prototype_translations', + 'count_pipe_groups', + 'create_force', + 'create_profiler', + 'create_random_generator', + 'create_surface', + 'decode_string', + 'delete_surface', + 'direction_to_string', + 'disable_replay', + 'disable_tips_and_tricks', + 'disable_tutorial_triggers', + 'encode_string', + 'evaluate_expression', + 'force_crc', + 'get_active_entities_count', + 'get_entity_by_tag', + 'get_filtered_achievement_prototypes', + 'get_filtered_decorative_prototypes', + 'get_filtered_entity_prototypes', + 'get_filtered_equipment_prototypes', + 'get_filtered_fluid_prototypes', + 'get_filtered_item_prototypes', + 'get_filtered_mod_setting_prototypes', + 'get_filtered_recipe_prototypes', + 'get_filtered_technology_prototypes', + 'get_filtered_tile_prototypes', + 'get_map_exchange_string', + 'get_player', + 'get_surface', + 'get_train_stops', + 'help', + 'is_demo', + 'is_multiplayer', + 'is_valid_sound_path', + 'is_valid_sprite_path', + 'json_to_table', + 'kick_player', + 'log_recipe_locale', + 'merge_forces', + 'mute_player', + 'parse_map_exchange_string', + 'play_sound', + 'print', + 'print_stack_size', + 'purge_player', + 'regenerate_entity', + 'reload_mods', + 'reload_script', + 'remove_offline_players', + 'remove_path', + 'reset_time_played', + 'save_atlas', + 'server_save', + 'set_game_state', + 'set_wait_for_screenshots_to_finish', + 'show_message_dialog', + 'table_to_json', + 'take_screenshot', + 'take_technology_screenshot', + 'unban_player', + 'unmute_player', + 'write_file', - -- @MOD@: Keep it organized, use this variable for anything that "NEEDS" to be global for some reason. - "MOD" - }, -} + achievement_prototypes = {read_only = true, other_fields = true}, + active_mods = {read_only = true, other_fields = true}, + ammo_category_prototypes = {read_only = true, other_fields = true}, + autoplace_control_prototypes = {read_only = true, other_fields = true}, + backer_names = {read_only = true, other_fields = true}, + connected_players = {read_only = true, other_fields = true}, + custom_input_prototypes = {read_only = true, other_fields = true}, + damage_prototypes = {read_only = true, other_fields = true}, + decorative_prototypes = {read_only = true, other_fields = true}, + default_map_gen_settings = {read_only = true, other_fields = true}, + difficulty = {read_only = true, other_fields = true}, + difficulty_settings = {read_only = true, other_fields = true}, + entity_prototypes = {read_only = true, other_fields = true}, + equipment_category_prototypes = {read_only = true, other_fields = true}, + equipment_grid_prototypes = {read_only = true, other_fields = true}, + equipment_prototypes = {read_only = true, other_fields = true}, + finished = {read_only = true, other_fields = true}, + fluid_prototypes = {read_only = true, other_fields = true}, + forces = {read_only = true, other_fields = true}, + fuel_category_prototypes = {read_only = true, other_fields = true}, + item_group_prototypes = {read_only = true, other_fields = true}, + item_prototypes = {read_only = true, other_fields = true}, + item_subgroup_prototypes = {read_only = true, other_fields = true}, + map_settings = {read_only = true, other_fields = true}, + mod_setting_prototypes = {read_only = true, other_fields = true}, + module_category_prototypes = {read_only = true, other_fields = true}, + named_noise_expressions = {read_only = true, other_fields = true}, + noise_layer_prototypes = {read_only = true, other_fields = true}, + object_name = {read_only = true, other_fields = true}, + particle_prototypes = {read_only = true, other_fields = true}, + permissions = {read_only = true, other_fields = true}, + player = {read_only = true, other_fields = true}, + players = {read_only = true, other_fields = true}, + pollution_statistics = {read_only = true, other_fields = true}, + recipe_category_prototypes = {read_only = true, other_fields = true}, + recipe_prototypes = {read_only = true, other_fields = true}, + resource_category_prototypes = {read_only = true, other_fields = true}, + shortcut_prototypes = {read_only = true, other_fields = true}, + styles = {read_only = true, other_fields = true}, + surfaces = {read_only = true, other_fields = true}, + technology_prototypes = {read_only = true, other_fields = true}, + tick = {read_only = true, other_fields = true}, + ticks_played = {read_only = true, other_fields = true}, + tile_prototypes = {read_only = true, other_fields = true}, + trivial_smoke_prototypes = {read_only = true, other_fields = true}, + virtual_signal_prototypes = {read_only = true, other_fields = true}, -stds.factorio_data = { - - read_globals = { - data = { - fields = { - raw = { - other_fields = true, - read_only = false + autosave_enabled = {read_only = false, other_fields = false}, + draw_resource_selection = {read_only = false, other_fields = false}, + enemy_has_vision_on_land_mines = {read_only = false, other_fields = false}, + speed = {read_only = false, other_fields = false}, + tick_paused = {read_only = false, other_fields = false}, + ticks_to_run = {read_only = false, other_fields = false} }, - "extend", "is_demo" }, }, - settings = { - fields = { - "startup", "global", "player", + globals = { + -- @global@: The global dictionary, useful for storing data persistent across a save-load cycle. + -- Writing access is given to the mod-id field (for mod-wise saved data). + -- (http://lua-api.factorio.com/latest/Global.html) + "global", + + -- @MOD@: Keep it organized, use this variable for anything that "NEEDS" to be global for some reason. + "MOD" + }, + } + + stds.factorio_data = { + + read_globals = { + data = { + fields = { + raw = { + other_fields = true, + read_only = false + }, + "extend", "is_demo" + }, }, - }, - --Popular mods - angelsmods = { - other_fields = true - }, + settings = { + fields = { + "startup", "global", "player", "get", "get_startup" + }, + }, + + mods = { + other_fields = true + }, + + -- Popular mods that think they need globals! + angelsmods = { + other_fields = true + }, + + -- Popular mods that think they need globals! + bobmods = { + other_fields = true + }, - bobmods = { - other_fields = true - }, - mods = { - other_fields = true } } -} +end -------------------------------------------------------------------------------- ---[Factorio Data]-------------------------------------------------------------- -------------------------------------------------------------------------------- -stds.factorio_base_control = { - read_globals = {"silo_script", "mod_gui", "camera"} -} - -stds.factorio_base_scenarios = { - globals = { - "check_automate_science_packs_advice", "check_research_hints", "check_supplies", "manage_attacks", "all_dead", - "on_win", "difficulty_number", "init_attack_data", "handle_attacks", "count_items_in_container", "progress", "scanned", - "check_light", "check_machine_gun", "level", "story_table", - - "tightspot_prices", "tightspot_make_offer", "tightspot_init", "tightspot_get_required_balance", - "tightspot_init_level", "tightspot_init_spending_frame", "tightspot_init_progress_frame", "tightspot_update_progress", "tightspot_update_spending", - "tightspot_get_missing_to_win", "tightspot_sell_back", "tightspot_start_level", "tightspot_show_level_description", "tightspot_update_speed_label", - "map_ignore", "tightspot_check_level", "land_price", - - "transport_belt_madness_init", "transport_belt_madness_init_level", "transport_belt_madness_create_chests", "transport_belt_madness_fill_chests", - "transport_belt_madness_start_level", "map_ignore", "map_clear", "map_load", "map_save", "transport_belt_madness_show_level_description", - "transport_belt_madness_check_level", "transport_belt_madness_next_level", "transport_belt_madness_clear_level", "transport_belt_madness_contains_next_level", - - "restricted", "check_built_items", "result", "disable_combat_technologies", "apply_character_modifiers", "apply_combat_modifiers", "apply_balance", - "load_config", "starting_area_constant", "create_next_surface", "end_round", "prepare_next_round", "silo_died","choose_joining_gui", - "destroy_joining_guis", "create_random_join_gui", "create_auto_assign_gui", "create_pick_join_gui", "create_config_gui", "make_config_table", "default", - "make_team_gui", "make_team_gui_config", "add_team_button_press", "trash_team_button_press", "remove_team_from_team_table", "add_team_to_team_table", - "set_teams_from_gui", "on_team_button_press", "make_color_dropdown", "create_balance_option", "create_disable_frame", "disable_frame", "parse_disabled_items", - "set_balance_settings", "config_confirm", "parse_config_from_gui", "get_color", "roll_starting_area", "delete_roll_surfaces", "auto_assign", - "destroy_config_for_all", "prepare_map", "set_evolution_factor", "update_players_on_team_count", "random_join", "init_player_gui", - "destroy_player_gui", "objective_button_press", "admin_button_press", "admin_frame_button_press", "diplomacy_button_press", "update_diplomacy_frame", - "diplomacy_frame_button_press", "team_changed_diplomacy", "diplomacy_check_press", "get_stance", "give_inventory", "setup_teams", "disable_items_for_all", - "set_random_team", "set_diplomacy", "create_spawn_positions", "set_spawn_position", "set_team_together_spawns", "chart_starting_area_for_force_spawns", - "check_starting_area_chunks_are_generated", "check_player_color", "check_round_start", "clear_starting_area_enemies", "check_no_rush_end", "check_no_rush_players", - "finish_setup", "chart_area_for_force", "setup_start_area_copy", "update_copy_progress", "update_progress_bar", "copy_paste_starting_area_tiles", - "copy_paste_starting_area_entities", "create_silo_for_force", "setup_research", "on_chunk_generated", "get_distance_to_nearest_spawn", - "create_wall_for_force", "fpn", "give_items", "create_item_frame", "create_technologies_frame", "create_cheat_frame", "create_day_frame", - "time_modifier", "points_per_second_start", "points_per_second_level_subtract", "levels", "update_info", "get_time_left", "update_time_left", - "on_joined", "make_frame", "update_frame", "update_table", "calculate_task_item_multiplayer", "setup_config", "select_from_probability_table", - "select_inventory", "select_equipment", "select_challange_type", "save_round_statistics", "start_challenge", "create_teams", "set_areas", - "decide_player_team", "set_teams", "refresh_leaderboard", "set_player", "generate_technology_list", "generate_research_task","setup_unlocks", - "check_technology_progress", "generate_production_task", "generate_shopping_list_task", "set_gui_flow_table", "create_visibility_button", - "check_item_lists", "update_task_gui", "check_end_of_round", "end_round_gui_update", "try_to_check_victory", "update_gui", "check_start_round", - "check_start_set_areas", "check_start_setting_entities", "check_set_areas", "check_clear_areas", "check_chests", "check_chests_shopping_list", - "check_chests_production", "check_input_chests", "fill_input_chests", "check_victory", "shopping_task_finished", "calculate_force_points", - "update_research_task_table", "update_production_task_table", "update_shopping_list_task_table", "create_joined_game_gui", "pre_ending_round", - "player_ending_prompt", "update_end_timer", "update_begin_timer", "team_finished", "save_points_list", "give_force_players_points", - "update_winners_list", "set_spectator", "set_character", "give_starting_inventory", "give_equipment", "shuffle_table", "format_time", - "spairs", "fill_leaderboard", "create_grid", "simple_entities", "save_map_data", "clear_map", "create_tiles", "recreate_entities", - "map_sets", "give_points", "init_forces", "init_globals", "init_unit_settings", "check_next_wave", "next_wave", "calculate_wave_power", - "wave_end", "make_next_spawn_tick", "check_spawn_units", "get_wave_units", "spawn_units", "randomize_ore", "set_command", "command_straglers", - "unit_config", "make_next_wave_tick", "time_to_next_wave", "time_to_wave_end", "rocket_died", "unit_died", "get_bounty_price", "setup_waypoints", - "insert_items", "give_starting_equipment", "give_spawn_equipment", "next_round_button_visible", "gui_init", "create_wave_frame", "create_money_frame", - "create_upgrade_gui", "update_upgrade_listing", "upgrade_research", "get_upgrades", "get_money", "update_connected_players", "update_round_number", - "set_research", "set_recipes", "check_deconstruction", "check_blueprint_placement", "loop_entities", "experiment_items", - "setup", "story_gui_click", "clear_surface", "add_run_trains_button", "puzzle_condition", "basic_signals", - "loop_trains", "Y_offset", "ghosts_1", "ghosts_2", "required_path", "through_wall_path", "count", "check_built_real_rail", - "current_ghosts_count", "other", "rails", "set_rails", "straight_section", "late_entities", "entities", "stop", - "get_spawn_coordinate", - - --tutorials - "intermission", "create_entities_on_tick", "on_player_created", "required_count", "non_player_entities", "clear_rails", - "chest", "damage", "furnace", "init_prototypes", "build_infi_table", "junk", "update_player_tags", "time_left", "team_production", - "create_task_frame", "create_visibilty_buttons", "update_leaderboard", "in_in_area" +do -- Factorio Base/Core STDs-- + stds.factorio_base_control = { + read_globals = {"silo_script", "mod_gui", "camera"} } -} -stds.factorio_base_data = { - globals = { - --Style - "make_cursor_box", "make_full_cursor_box", - "default_container_padding", "default_orange_color", "default_light_orange_color", "warning_red_color", - "achievement_green_color", "achievement_tan_color", "orangebuttongraphcialset", "bluebuttongraphcialset", - "bonus_gui_ordering", "trivial_smoke", "technology_slot_base_width", "technology_slot_base_height", "default_frame_font_vertical_compensation", + stds.factorio_base_scenarios = { + globals = { + "check_automate_science_packs_advice", "check_research_hints", "check_supplies", "manage_attacks", "all_dead", + "on_win", "difficulty_number", "init_attack_data", "handle_attacks", "count_items_in_container", "progress", "scanned", + "check_light", "check_machine_gun", "level", "story_table", - --Belts - "transport_belt_connector_frame_sprites", "transport_belt_circuit_wire_connection_point", "transport_belt_circuit_wire_max_distance", - "transport_belt_circuit_connector_sprites", "ending_patch_prototype", "basic_belt_horizontal", "basic_belt_vertical", - "basic_belt_ending_top", "basic_belt_ending_bottom", "basic_belt_ending_side", "basic_belt_starting_top", "basic_belt_starting_bottom", - "basic_belt_starting_side", "fast_belt_horizontal", "fast_belt_vertical", "fast_belt_ending_top", "fast_belt_ending_bottom", - "fast_belt_ending_side", "fast_belt_starting_top", "fast_belt_starting_bottom", "fast_belt_starting_side", "express_belt_horizontal", - "express_belt_vertical", "express_belt_ending_top", "express_belt_ending_bottom", "express_belt_ending_side", "express_belt_starting_top", - "express_belt_starting_bottom", "express_belt_starting_side", + "tightspot_prices", "tightspot_make_offer", "tightspot_init", "tightspot_get_required_balance", + "tightspot_init_level", "tightspot_init_spending_frame", "tightspot_init_progress_frame", "tightspot_update_progress", "tightspot_update_spending", + "tightspot_get_missing_to_win", "tightspot_sell_back", "tightspot_start_level", "tightspot_show_level_description", "tightspot_update_speed_label", + "map_ignore", "tightspot_check_level", "land_price", - --Circuit Connectors - "circuit_connector_definitions", "default_circuit_wire_max_distance", "inserter_circuit_wire_max_distance", - "universal_connector_template", "belt_connector_template", "belt_frame_connector_template", "inserter_connector_template", + "transport_belt_madness_init", "transport_belt_madness_init_level", "transport_belt_madness_create_chests", "transport_belt_madness_fill_chests", + "transport_belt_madness_start_level", "map_ignore", "map_clear", "map_load", "map_save", "transport_belt_madness_show_level_description", + "transport_belt_madness_check_level", "transport_belt_madness_next_level", "transport_belt_madness_clear_level", "transport_belt_madness_contains_next_level", - --Inserter Circuit Connectors - "inserter_circuit_wire_max_distance", "inserter_default_stack_control_input_signal", + "restricted", "check_built_items", "result", "disable_combat_technologies", "apply_character_modifiers", "apply_combat_modifiers", "apply_balance", + "load_config", "starting_area_constant", "create_next_surface", "end_round", "prepare_next_round", "silo_died","choose_joining_gui", + "destroy_joining_guis", "create_random_join_gui", "create_auto_assign_gui", "create_pick_join_gui", "create_config_gui", "make_config_table", "default", + "make_team_gui", "make_team_gui_config", "add_team_button_press", "trash_team_button_press", "remove_team_from_team_table", "add_team_to_team_table", + "set_teams_from_gui", "on_team_button_press", "make_color_dropdown", "create_balance_option", "create_disable_frame", "disable_frame", "parse_disabled_items", + "set_balance_settings", "config_confirm", "parse_config_from_gui", "get_color", "roll_starting_area", "delete_roll_surfaces", "auto_assign", + "destroy_config_for_all", "prepare_map", "set_evolution_factor", "update_players_on_team_count", "random_join", "init_player_gui", + "destroy_player_gui", "objective_button_press", "admin_button_press", "admin_frame_button_press", "diplomacy_button_press", "update_diplomacy_frame", + "diplomacy_frame_button_press", "team_changed_diplomacy", "diplomacy_check_press", "get_stance", "give_inventory", "setup_teams", "disable_items_for_all", + "set_random_team", "set_diplomacy", "create_spawn_positions", "set_spawn_position", "set_team_together_spawns", "chart_starting_area_for_force_spawns", + "check_starting_area_chunks_are_generated", "check_player_color", "check_round_start", "clear_starting_area_enemies", "check_no_rush_end", "check_no_rush_players", + "finish_setup", "chart_area_for_force", "setup_start_area_copy", "update_copy_progress", "update_progress_bar", "copy_paste_starting_area_tiles", + "copy_paste_starting_area_entities", "create_silo_for_force", "setup_research", "on_chunk_generated", "get_distance_to_nearest_spawn", + "create_wall_for_force", "fpn", "give_items", "create_item_frame", "create_technologies_frame", "create_cheat_frame", "create_day_frame", + "time_modifier", "points_per_second_start", "points_per_second_level_subtract", "levels", "update_info", "get_time_left", "update_time_left", + "on_joined", "make_frame", "update_frame", "update_table", "calculate_task_item_multiplayer", "setup_config", "select_from_probability_table", + "select_inventory", "select_equipment", "select_challange_type", "save_round_statistics", "start_challenge", "create_teams", "set_areas", + "decide_player_team", "set_teams", "refresh_leaderboard", "set_player", "generate_technology_list", "generate_research_task","setup_unlocks", + "check_technology_progress", "generate_production_task", "generate_shopping_list_task", "set_gui_flow_table", "create_visibility_button", + "check_item_lists", "update_task_gui", "check_end_of_round", "end_round_gui_update", "try_to_check_victory", "update_gui", "check_start_round", + "check_start_set_areas", "check_start_setting_entities", "check_set_areas", "check_clear_areas", "check_chests", "check_chests_shopping_list", + "check_chests_production", "check_input_chests", "fill_input_chests", "check_victory", "shopping_task_finished", "calculate_force_points", + "update_research_task_table", "update_production_task_table", "update_shopping_list_task_table", "create_joined_game_gui", "pre_ending_round", + "player_ending_prompt", "update_end_timer", "update_begin_timer", "team_finished", "save_points_list", "give_force_players_points", + "update_winners_list", "set_spectator", "set_character", "give_starting_inventory", "give_equipment", "shuffle_table", "format_time", + "spairs", "fill_leaderboard", "create_grid", "simple_entities", "save_map_data", "clear_map", "create_tiles", "recreate_entities", + "map_sets", "give_points", "init_forces", "init_globals", "init_unit_settings", "check_next_wave", "next_wave", "calculate_wave_power", + "wave_end", "make_next_spawn_tick", "check_spawn_units", "get_wave_units", "spawn_units", "randomize_ore", "set_command", "command_straglers", + "unit_config", "make_next_wave_tick", "time_to_next_wave", "time_to_wave_end", "rocket_died", "unit_died", "get_bounty_price", "setup_waypoints", + "insert_items", "give_starting_equipment", "give_spawn_equipment", "next_round_button_visible", "gui_init", "create_wave_frame", "create_money_frame", + "create_upgrade_gui", "update_upgrade_listing", "upgrade_research", "get_upgrades", "get_money", "update_connected_players", "update_round_number", + "set_research", "set_recipes", "check_deconstruction", "check_blueprint_placement", "loop_entities", "experiment_items", + "setup", "story_gui_click", "clear_surface", "add_run_trains_button", "puzzle_condition", "basic_signals", + "loop_trains", "Y_offset", "ghosts_1", "ghosts_2", "required_path", "through_wall_path", "count", "check_built_real_rail", + "current_ghosts_count", "other", "rails", "set_rails", "straight_section", "late_entities", "entities", "stop", + "get_spawn_coordinate", - --Sounds/beams - "make_heavy_gunshot_sounds", "make_light_gunshot_sounds", "make_laser_sounds", - - --Gun/Laser - "gun_turret_extension", "gun_turret_extension_shadow", "gun_turret_extension_mask", "gun_turret_attack", - "laser_turret_extension", "laser_turret_extension_shadow", "laser_turret_extension_mask", - - --Pipes - "pipecoverspictures", "pipepictures", "assembler2pipepictures", "assembler3pipepictures", "make_heat_pipe_pictures", - - --Combinators - "generate_arithmetic_combinator", "generate_decider_combinator", "generate_constant_combinator", - - --Rail - "destroyed_rail_pictures", "rail_pictures", "rail_pictures_internal", "standard_train_wheels", "drive_over_tie", - "rolling_stock_back_light", "rolling_stock_stand_by_light", - - --Enemies - "make_enemy_autoplace", "make_enemy_spawner_autoplace", "make_enemy_worm_autoplace", - "make_spitter_attack_animation", "make_spitter_run_animation", "make_spitter_dying_animation", - "make_spitter_attack_parameters", "make_spitter_roars", "make_spitter_dying_sounds", - "make_spawner_idle_animation", "make_spawner_die_animation", - "make_biter_run_animation", "make_biter_attack_animation", "make_biter_die_animation", - "make_biter_roars", "make_biter_dying_sounds", "make_biter_calls", - "make_worm_roars", "make_worm_dying_sounds", "make_worm_folded_animation", "make_worm_preparing_animation", - "make_worm_prepared_animation", "make_worm_attack_animation", "make_worm_die_animation", - - --Other - "tile_variations_template", "make_water_autoplace_settings", - "make_unit_melee_ammo_type", "make_trivial_smoke", "make_4way_animation_from_spritesheet", "flying_robot_sounds", - "productivitymodulelimitation", "crash_trigger", "capsule_smoke", "make_beam", "playeranimations", - "make_blood_tint", "make_shadow_tint", - - --tiles - "water_transition_template", "make_water_transition_template", "water_autoplace_settings", "water_tile_type_names", - "patch_for_inner_corner_of_transition_between_transition", + --tutorials + "intermission", "create_entities_on_tick", "on_player_created", "required_count", "non_player_entities", "clear_rails", + "chest", "damage", "furnace", "init_prototypes", "build_infi_table", "junk", "update_player_tags", "time_left", "team_production", + "create_task_frame", "create_visibilty_buttons", "update_leaderboard", "in_in_area" + } } -} -stds.factorio_base_story = { - globals = { - "story_init_helpers", "story_update_table", "story_init", "story_update", "story_on_tick", "story_add_update", - "story_remove_update", "story_jump_to", "story_elapsed", "story_elapsed_check", "story_show_message_dialog", - "set_goal", "player_set_goal", "on_player_joined", "flash_goal", "set_info", "player_set_info", "export_entities", - "list", "recreate_entities", "entity_to_connect", "limit_camera", "find_gui_recursive", "enable_entity_export", - "add_button", "on_gui_click", "set_continue_button_style", "add_message_log", "story_add_message_log", - "player_add_message_log", "message_log_frame", "message_log_scrollpane", "message_log_close_button", - "message_log_table", "toggle_message_log_button", "toggle_objective_button", "message_log_init", - "add_gui_recursive", "add_toggle_message_log_button", "add_toggle_objective_button", "mod_gui", - "flash_message_log_button", "flash_message_log_on_tick", "story_gui_click", "story_points_by_name", "story_branches", - "player", "surface", "deconstruct_on_tick", "recreate_entities_on_tick", "flying_congrats", "story_table" + stds.factorio_base_data = { + globals = { + --Style + "make_cursor_box", "make_full_cursor_box", + "default_container_padding", "default_orange_color", "default_light_orange_color", "warning_red_color", + "achievement_green_color", "achievement_tan_color", "orangebuttongraphcialset", "bluebuttongraphcialset", + "bonus_gui_ordering", "trivial_smoke", "technology_slot_base_width", "technology_slot_base_height", "default_frame_font_vertical_compensation", + + --Belts + "transport_belt_connector_frame_sprites", "transport_belt_circuit_wire_connection_point", "transport_belt_circuit_wire_max_distance", + "transport_belt_circuit_connector_sprites", "ending_patch_prototype", "basic_belt_horizontal", "basic_belt_vertical", + "basic_belt_ending_top", "basic_belt_ending_bottom", "basic_belt_ending_side", "basic_belt_starting_top", "basic_belt_starting_bottom", + "basic_belt_starting_side", "fast_belt_horizontal", "fast_belt_vertical", "fast_belt_ending_top", "fast_belt_ending_bottom", + "fast_belt_ending_side", "fast_belt_starting_top", "fast_belt_starting_bottom", "fast_belt_starting_side", "express_belt_horizontal", + "express_belt_vertical", "express_belt_ending_top", "express_belt_ending_bottom", "express_belt_ending_side", "express_belt_starting_top", + "express_belt_starting_bottom", "express_belt_starting_side", + + --Circuit Connectors + "circuit_connector_definitions", "default_circuit_wire_max_distance", "inserter_circuit_wire_max_distance", + "universal_connector_template", "belt_connector_template", "belt_frame_connector_template", "inserter_connector_template", + + --Inserter Circuit Connectors + "inserter_circuit_wire_max_distance", "inserter_default_stack_control_input_signal", + + --Sounds/beams + "make_heavy_gunshot_sounds", "make_light_gunshot_sounds", "make_laser_sounds", + + --Gun/Laser + "gun_turret_extension", "gun_turret_extension_shadow", "gun_turret_extension_mask", "gun_turret_attack", + "laser_turret_extension", "laser_turret_extension_shadow", "laser_turret_extension_mask", + + --Pipes + "pipecoverspictures", "pipepictures", "assembler2pipepictures", "assembler3pipepictures", "make_heat_pipe_pictures", + + --Combinators + "generate_arithmetic_combinator", "generate_decider_combinator", "generate_constant_combinator", + + --Rail + "destroyed_rail_pictures", "rail_pictures", "rail_pictures_internal", "standard_train_wheels", "drive_over_tie", + "rolling_stock_back_light", "rolling_stock_stand_by_light", + + --Enemies + "make_enemy_autoplace", "make_enemy_spawner_autoplace", "make_enemy_worm_autoplace", + "make_spitter_attack_animation", "make_spitter_run_animation", "make_spitter_dying_animation", + "make_spitter_attack_parameters", "make_spitter_roars", "make_spitter_dying_sounds", + "make_spawner_idle_animation", "make_spawner_die_animation", + "make_biter_run_animation", "make_biter_attack_animation", "make_biter_die_animation", + "make_biter_roars", "make_biter_dying_sounds", "make_biter_calls", + "make_worm_roars", "make_worm_dying_sounds", "make_worm_folded_animation", "make_worm_preparing_animation", + "make_worm_prepared_animation", "make_worm_attack_animation", "make_worm_die_animation", + + --Other + "tile_variations_template", "make_water_autoplace_settings", + "make_unit_melee_ammo_type", "make_trivial_smoke", "make_4way_animation_from_spritesheet", "flying_robot_sounds", + "productivitymodulelimitation", "crash_trigger", "capsule_smoke", "make_beam", "playeranimations", + "make_blood_tint", "make_shadow_tint", + + --tiles + "water_transition_template", "make_water_transition_template", "water_autoplace_settings", "water_tile_type_names", + "patch_for_inner_corner_of_transition_between_transition", + } } -} -stds.factorio_circuit_connector_generated = { - globals = { - 'default_circuit_wire_max_distance', 'circuit_connector_definitions', 'universal_connector_template', - 'belt_connector_template', 'belt_frame_connector_template', 'inserter_connector_template', 'inserter_connector_template', - 'inserter_circuit_wire_max_distance', 'inserter_default_stack_control_input_signal', 'transport_belt_connector_frame_sprites', - 'transport_belt_circuit_wire_max_distance', + stds.factorio_base_story = { + globals = { + "story_init_helpers", "story_update_table", "story_init", "story_update", "story_on_tick", "story_add_update", + "story_remove_update", "story_jump_to", "story_elapsed", "story_elapsed_check", "story_show_message_dialog", + "set_goal", "player_set_goal", "on_player_joined", "flash_goal", "set_info", "player_set_info", "export_entities", + "list", "recreate_entities", "entity_to_connect", "limit_camera", "find_gui_recursive", "enable_entity_export", + "add_button", "on_gui_click", "set_continue_button_style", "add_message_log", "story_add_message_log", + "player_add_message_log", "message_log_frame", "message_log_scrollpane", "message_log_close_button", + "message_log_table", "toggle_message_log_button", "toggle_objective_button", "message_log_init", + "add_gui_recursive", "add_toggle_message_log_button", "add_toggle_objective_button", "mod_gui", + "flash_message_log_button", "flash_message_log_on_tick", "story_gui_click", "story_points_by_name", "story_branches", + "player", "surface", "deconstruct_on_tick", "recreate_entities_on_tick", "flying_congrats", "story_table" + } } -} ---(( STDLIB ))-- -stds.stdlib = { - read_globals = { - table = { - fields = { - "map", "avg", "count_keys", "sum", "max", "remove", "insert", "invert", "first", "sort", "compare", "maxn", "any", "array_to_dictionary", - "each", "flatten", "keys", "filter", "remove_keys", "flexcopy", "find", "fullcopy", "values", "pack", "deepcopy", "concat", "clear", "min", - "is_empty", "merge", "size", "dictionary_merge", "unpack", "last" + stds.factorio_circuit_connector_generated = { + globals = { + 'default_circuit_wire_max_distance', 'circuit_connector_definitions', 'universal_connector_template', + 'belt_connector_template', 'belt_frame_connector_template', 'inserter_connector_template', 'inserter_connector_template', + 'inserter_circuit_wire_max_distance', 'inserter_default_stack_control_input_signal', 'transport_belt_connector_frame_sprites', + 'transport_belt_circuit_wire_max_distance', + } + } +end + +do -- STDLIB STDs-- + stds.stdlib = { + read_globals = {}, + globals = { + 'STDLIB', + 'prequire', + 'rawtostring', + 'traceback', + 'data_traceback', + 'inspect', + 'serpent', + 'inline_if', + 'install', + 'log', + 'concat', + 'GAME', + 'AREA', + 'POSITION', + 'TILE', + 'SURFACE', + 'CHUNK', + 'COLOR', + 'ENTITY', + 'INVENTORY', + 'RESOURCE', + 'CONFIG', + 'LOGGER', + 'QUEUE', + 'EVENT', + 'GUI', + 'PLAYER', + 'FORCE', + 'MATH', + 'STRING', + 'TABLE' + } + } + + stds.stdlib_control = {} + + stds.stdlib_data = { + globals = { + 'DATA', + 'RECIPE', + 'ITEM', + 'FLUID', + 'ENTITY', + 'TECHNOLOGY', + 'CATEGORY' + } + } +end + +do -- Love STDs + stds.love_extra = { + read_globals = { + love = { + fields = { + arg = { + fields = { + 'parseGameArguments', + 'parseOption', + 'getLow', + 'optionIndices', + 'options' + } + } + } }, + 'coroutine', + 'io', + 'socket', + 'dofile', + 'loadfile' }, - string = { - fields = { - "is_space", "is_empty", "match", "title", "upper", "gmatch", "trim", "split", "len", "ordinal_suffix", "dump", "shorten", "reverse", - "ends_with", "byte", "starts_with", "join", "is_alpha", "lower", "is_upper", "is_digit", "is_alnum", "rjust", "center", "ljust", "format", - "char", "is_lower", "contains", "gsub", "find", "rep", "sub" - }, - }, - math = { - fields = { - "asin", "max", "modf", "midrange_mean", "pow", "ldexp", "maxuint16", "fmod", "round_to", "randomseed", "huge", "harmonic_mean", "tan", - "maxint32", "quadratic_mean", "pi", "energetic_mean", "minint8", "frexp", "generalized_mean", "rad", "sin", "sinh", "min", "geometric_mean", - "atan", "avg", "cosh", "maxint8", "arithmetic_mean", "exp", "sum", "round", "maxuint64", "minint64", "ceil", "maxint64", "atan2", "floor_to", - "floor", "log", "maxint16", "minint16", "tanh", "acos", "deg", "cos", "log10", "maxuint8", "abs", "weighted_mean", "random", "maxuint32", - "sqrt", "minint32" + globals = { + love = { + fields = { + 'handlers' + } } - }, - }, - globals = { - "prequire", "rawtostring", "traceback", "inspect", "serpent", "inline_if", - "GAME", "AREA", "POSITION", "TILE", "SURFACE", "CHUNK", "COLOR", "ENTITY", "INVENTORY", "RESOURCE", "CONFIG", "LOGGER", "QUEUE", - "EVENT", "GUI", "PLAYER", "FORCE", - "_STDLIB_NO_DEFINES_COLOR", "_STDLIB_NO_DEFINES_TIME", "_STDLIB_NO_STRING", "_STDLIB_NO_TABLE", "_STDLIB_NO_MATH" - } -} - -stds.stdlib_control = { -} - -stds.stdlib_data = { - globals = { - 'DATA', 'RECIPE', 'ITEM', 'FLUID', 'ENTITY', 'TECHNOLOGY', 'CATEGORY' - } -} --)) - ---(( FACTORIO DEFINES ))-- -stds.factorio_defines = { - globals = {"creative_mode_defines"}, - read_globals = { - defines = { - fields = { - events = { - fields = { - "on_tick", "on_gui_click", "on_gui_text_changed", "on_gui_checked_state_changed", "on_entity_died", "on_entity_damaged", "on_picked_up_item", - "on_built_entity", "on_sector_scanned", "on_player_mined_item", "on_put_item", "on_rocket_launched", "on_pre_player_mined_item", "on_chunk_generated", - "on_player_crafted_item", "on_robot_built_entity", "on_robot_pre_mined", "on_robot_mined", "on_research_started", "on_research_finished", - "on_player_rotated_entity", "on_marked_for_deconstruction", "on_canceled_deconstruction", "on_trigger_created_entity", "on_train_changed_state", - "on_player_created", "on_resource_depleted", "on_player_driving_changed_state", "on_force_created", "on_forces_merging", "on_player_cursor_stack_changed", - "on_pre_entity_settings_pasted", "on_entity_settings_pasted", "on_player_main_inventory_changed", "on_player_quickbar_inventory_changed", - "on_player_tool_inventory_changed", "on_player_armor_inventory_changed", "on_player_ammo_inventory_changed", "on_player_gun_inventory_changed", - "on_player_placed_equipment", "on_player_removed_equipment", "on_pre_player_died", "on_player_died", "on_player_respawned", "on_player_joined_game", - "on_player_left_game", "on_player_built_tile", "on_player_mined_tile", "on_robot_built_tile", "on_robot_mined_tile", "on_player_selected_area", - "on_player_alt_selected_area", "on_player_changed_surface", "on_selected_entity_changed", "on_market_item_purchased", "on_player_dropped_item", - "on_biter_base_built", "on_player_changed_force", "on_entity_renamed", "on_gui_selection_state_changed", "on_runtime_mod_setting_changed", - "on_difficulty_settings_changed", "on_surface_created", "on_surface_deleted", "on_pre_surface_deleted", "on_player_mined_entity", "on_robot_mined_entity", - "on_train_created", "on_gui_elem_changed", "on_player_setup_blueprint", "on_player_deconstructed_area", "on_player_configured_blueprint", "on_console_chat", - "on_console_command", "on_player_removed", "on_player_used_capsule", "script_raised_built", "script_raised_destroy", "script_raised_revive", - "on_player_promoted", "on_player_demoted", "on_combat_robot_expired", "on_player_changed_position", "on_mod_item_opened", "on_gui_opened", - "on_gui_closed", "on_gui_value_changed", "on_player_muted", "on_player_unmuted", "on_player_cheat_mode_enabled", "on_player_cheat_mode_disabled", - "on_character_corpse_expired", "on_pre_ghost_deconstructed", "on_player_pipette", "on_player_display_resolution_changed", "on_player_display_scale_changed", - "on_pre_player_crafted_item", "on_player_cancelled_crafting", "on_chunk_charted", "on_technology_effects_reset", "on_land_mine_armed", "on_forces_merged", - "on_player_trash_inventory_changed", "on_pre_player_left_game" - }, - }, - alert_type = { - fields = { - "custom", "entity_destroyed", "entity_under_attack", "no_material_for_construction", - "no_storage", "not_enough_construction_robots", "not_enough_repair_packs", "turret_fire", - }, - }, - chain_signal_state = { - fields = { - "all_open", "none", "none_open", "partially_open", - }, - }, - chunk_generated_status = { - fields = { - "basic_tiles", "corrected_tiles", "custom_tiles", "entities", "nothing", "tiles", - }, - }, - circuit_condition_index = { - fields = { - "arithmetic_combinator", "constant_combinator", "decider_combinator", "inserter_circuit", - "inserter_logistic", "lamp", "offshore_pump", "pump", - }, - }, - circuit_connector_id = { - fields = { - "accumulator", "combinator_input", "combinator_output", "constant_combinator", "container", - "electric_pole", "inserter", "lamp", "offshore_pump", "programmable_speaker", "pump", - "rail_signal", "roboport", "storage_tank", "wall", - }, - }, - command = { - fields = { - "attack", "attack_area", "build_base", "compound", "go_to_location", "group", "wander", - }, - }, - compound_command = { - fields = { - "logical_and", "logical_or", "return_last", - }, - }, - control_behavior = { - fields = { - inserter = { - fields = { - circuit_mode_of_operation = { - fields = { - "enable_disable", "none", "read_hand_contents", "set_filters", "set_stack_size", - }, - }, - hand_read_mode = { - fields = { - "hold", "pulse", - } - }, - }, - }, - lamp = { - fields = { - circuit_mode_of_operation = { - fields = { - "use_colors", - } - }, - }, - }, - logistic_container = { - fields = { - circuit_mode_of_operation = { - fields = { - "send_contents", "set_requests", - } - }, - }, - }, - mining_drill = { - fields = { - resource_read_mode = { - fields = { - "entire_patch", "this_miner", - } - }, - }, - }, - roboport = { - fields = { - circuit_mode_of_operation = { - fields = { - "read_logistics", "read_robot_stats", - } - }, - }, - }, - train_stop = { - fields = { - circuit_mode_of_operation = { - fields = { - "enable_disable", "read_from_train", "send_to_train", - } - }, - }, - }, - type = { - fields = { - "accumulator", "arithmetic_combinator", "constant_combinator", "container", - "decider_combinator", "generic_on_off", "inserter", "lamp", "logistic_container", - "rail_signal", "roboport", "storage_tank", "train_stop", "transport_belt", - }, - }, - }, - }, - controllers = { - fields = { - "character", "ghost", "god", - }, - }, - deconstruction_item = { - fields = { - entity_filter_mode = { - fields = { - "blacklist", "whitelist", - }, - }, - tile_filter_mode = { - fields = { - "always", "never", "normal", "only", - } - }, - }, - }, - difficulty = { - fields = { - "easy", "hard", "normal", - }, - }, - difficulty_settings = { - fields = { - recipe_difficulty = { - fields = { - "expensive", "normal", - }, - }, - technology_difficulty = { - fields = { - "expensive", "normal", - } - }, - }, - }, - direction = { - fields = { - "east", "north", "northeast", "northwest", "south", "southeast", "southwest", "west", - }, - }, - distraction = { - fields = { - "by_anything", "by_damage", "by_enemy", "none", - }, - }, - group_state = { - fields = { - "attacking_distraction", "attacking_target", "finished", "gathering", "moving", - }, - }, - gui_type = { - fields = { - "achievement", "blueprint_library", "bonus", "controller", "entity", "equipment", "item", - "kills", "logistic", "none", "other_player", "permissions", "production", "research", - "trains", "tutorials", "custom", - }, - }, - input_action = { - fields = { - "add_permission_group", "alt_select_area", "alt_select_blueprint_entities", "begin_mining", - "begin_mining_terrain", "build_item", "build_rail", "build_terrain", "cancel_craft", - "cancel_deconstruct", "cancel_new_blueprint", "cancel_research", "change_active_item_group_for_crafting", - "change_active_item_group_for_filters", "change_active_quick_bar", "change_arithmetic_combinator_parameters", - "change_blueprint_book_record_label", "change_decider_combinator_parameters", "change_item_label", - "change_picking_state", "change_programmable_speaker_alert_parameters", "change_programmable_speaker_circuit_parameters", - "change_programmable_speaker_parameters", "change_riding_state", "change_shooting_state", - "change_single_blueprint_record_label", "change_train_stop_station", "change_train_wait_condition", - "change_train_wait_condition_data", "clean_cursor_stack", "clear_blueprint", "clear_selected_blueprint", - "clear_selected_deconstruction_item", "connect_rolling_stock", "copy_entity_settings", "craft", - "craft_blueprint_record", "create_blueprint_like", "cursor_split", "cursor_transfer", "custom_input", - "cycle_blueprint_book_backwards", "cycle_blueprint_book_forwards", "deconstruct", "delete_blueprint_record", - "delete_custom_tag", "delete_permission_group", "disconnect_rolling_stock", "drop_blueprint_record", - "drop_item", "drop_to_blueprint_book", "edit_custom_tag", "edit_permission_group", "edit_train_schedule", - "export_blueprint", "fast_entity_split", "fast_entity_transfer", "grab_blueprint_record", "gui_checked_state_changed", - "gui_click", "gui_elem_selected", "gui_selection_state_changed", "gui_text_changed", "import_blueprint", - "import_blueprint_string", "inventory_split", "inventory_transfer", "launch_rocket", "market_offer", - "mod_settings_changed", "open_achievements_gui", "open_blueprint_library_gui", "open_blueprint_record", - "open_bonus_gui", "open_character_gui", "open_equipment", "open_gui", "open_item", "open_kills_gui", - "open_logistic_gui", "open_production_gui", "open_technology_gui", "open_train_gui", "open_train_station_gui", - "open_trains_gui", "open_tutorials_gui", "paste_entity_settings", "place_equipment", "remove_cables", - "reset_assembling_machine", "reverse_rotate_entity", "rotate_entity", "select_area", "select_blueprint_entities", - "select_entity_slot", "select_gun", "select_item", "select_tile_slot", "set_auto_launch_rocket", "set_autosort_inventory", - "set_behavior_mode", "set_blueprint_icon", "set_circuit_condition", "set_circuit_mode_of_operation", - "set_deconstruction_item_tile_selection_mode", "set_deconstruction_item_trees_only", "set_entity_color", - "set_entity_energy_property", "set_filter", "set_inserter_max_stack_size", "set_inventory_bar", "set_logistic_filter_item", - "set_logistic_filter_signal", "set_logistic_trash_filter_item", "set_research_finished_stops_game", "set_signal", - "set_single_blueprint_record_icon", "set_train_stopped", "set_use_item_groups", "setup_assembling_machine", - "setup_blueprint", "setup_single_blueprint_record", "shortcut_quick_bar_transfer", "smart_pipette", "stack_split", - "stack_transfer", "start_repair", "start_research", "start_walking", "switch_connect_to_logistic_network", - "switch_constant_combinator_state", "switch_power_switch_state", "switch_to_rename_stop_gui", "take_equipment", - "toggle_connect_center_back_tank", "toggle_connect_front_center_tank", "toggle_deconstruction_item_entity_filter_mode", - "toggle_deconstruction_item_tile_filter_mode", "toggle_driving", "toggle_enable_vehicle_logistics_while_moving", - "toggle_entity_on_off_state", "toggle_show_entity_info", "use_ability", "use_item", "wire_dragging", "write_to_console", - }, - }, - inventory = { - fields = { - "assembling_machine_input", "assembling_machine_modules", "assembling_machine_output", "beacon_modules", - "burnt_result", "car_ammo", "car_trunk", "cargo_wagon", "chest", "fuel", "furnace_modules", - "furnace_result", "furnace_source", "god_main", "god_quickbar", "item_main", "lab_input", "lab_modules", - "mining_drill_modules", "player_ammo", "player_armor", "player_guns", "player_main", "player_quickbar", - "player_tools", "player_trash", "player_vehicle", "roboport_material", "roboport_robot", "rocket_silo_result", - "rocket_silo_rocket", "turret_ammo", "rocket", "character_corpse" - }, - }, - logistic_member_index = { - fields = { - "character_provider", "character_requester", "character_storage", "generic_on_off_behavior", "logistic_container", "vehicle_storage", - }, - }, - logistic_mode = { - fields = { - "active_provider", "none", "passive_provider", "requester", "storage", "buffer" - }, - }, - mouse_button_type = { - fields = { - "left", "middle", "none", "right", - }, - }, - rail_connection_direction = { - fields = { - "left", "none", "right", "straight", - }, - }, - rail_direction = { - fields = { - "back", "front", - }, - }, - riding = { - fields = { - acceleration = { - fields = { - "accelerating", "braking", "nothing", "reversing", - }, - }, - direction = { - fields = { - "left", "right", "straight", - } - }, - }, - }, - shooting = { - fields = { - "not_shooting", "shooting_enemies", "shooting_selected", - }, - }, - signal_state = { - fields = { - "closed", "open", "reserved", "reserved_by_circuit_network", - }, - }, - train_state = { - fields = { - "arrive_signal", "arrive_station", "manual_control", "manual_control_stop", "no_path", "no_schedule", - "on_the_path", "path_lost", "stop_for_auto_control", "wait_signal", "wait_station", - }, - }, - transport_line = { - fields = { - "left_line", "left_split_line", "left_underground_line", "right_line", "right_split_line", "right_underground_line", - "secondary_left_line", "secondary_left_split_line", "secondary_right_line", "secondary_right_split_line", - }, - }, - wire_type = { - fields = { - "copper", "green", "red", - } - }, - -- Deprecated - colors = { - other_fields = true, - }, - -- Deprecated - anticolors = { - other_fields = true, - }, - -- Deprecated - lightcolors = { - other_fields = true, - }, - color = { - other_fields = true, - }, - anticolor = { - other_fields = true, - }, - lightcolor = { - other_fields = true, - }, - time = { - fields = { - "second", "minute", "hour", "day", "week", "month", "year", - } - }, - }, } } -} --)) +end ---[[ +do -- Factorio Defines STDs-- + stds.factorio_defines = { + read_globals = { + defines = { + fields = { + alert_type = { + fields = { + 'entity_destroyed', + 'entity_under_attack', + 'not_enough_construction_robots', + 'no_material_for_construction', + 'not_enough_repair_packs', + 'turret_fire', + 'custom', + 'no_storage', + 'train_out_of_fuel', + 'fluid_mixing' + } + }, + behavior_result = { + fields = { + 'in_progress', + 'fail', + 'success', + 'deleted' + } + }, + build_check_type = { + fields = { + 'script', + 'manual', + 'ghost_place', + 'ghost_revive' + } + }, + chain_signal_state = { + fields = { + 'all_open', + 'partially_open', + 'none_open' + } + }, + chunk_generated_status = { + fields = { + 'nothing', + 'custom_tiles', + 'basic_tiles', + 'corrected_tiles', + 'tiles', + 'entities' + } + }, + circuit_condition_index = { + fields = { + 'inserter_circuit', + 'inserter_logistic', + 'lamp', + 'arithmetic_combinator', + 'decider_combinator', + 'constant_combinator', + 'offshore_pump', + 'pump' + } + }, + circuit_connector_id = { + fields = { + 'accumulator', + 'constant_combinator', + 'container', + 'programmable_speaker', + 'rail_signal', + 'rail_chain_signal', + 'roboport', + 'storage_tank', + 'wall', + 'electric_pole', + 'inserter', + 'lamp', + 'combinator_input', + 'combinator_output', + 'offshore_pump', + 'pump' + } + }, + command = { + fields = { + 'attack', + 'go_to_location', + 'compound', + 'group', + 'attack_area', + 'wander', + 'flee', + 'stop', + 'build_base' + } + }, + compound_command = { + fields = { + 'logical_and', + 'logical_or', + 'return_last' + } + }, + control_behavior = { + fields = { + inserter = { + fields = { + circuit_mode_of_operation = { + fields = { + 'enable_disable', + 'set_filters', + 'read_hand_contents', + 'set_stack_size' + } + }, + hand_read_mode = { + fields = { + 'hold', + 'pulse' + } + } + } + }, + lamp = { + fields = { + circuit_mode_of_operation = { + fields = { + 'use_colors' + } + } + } + }, + logistic_container = { + fields = { + circuit_mode_of_operation = { + fields = { + 'send_contents', + 'set_requests' + } + } + } + }, + mining_drill = { + fields = { + resource_read_mode = { + fields = { + 'this_miner', + 'entire_patch' + } + } + } + }, + roboport = { + fields = { + circuit_mode_of_operation = { + fields = { + 'read_logistics', + 'read_robot_stats' + } + } + } + }, + train_stop = { + fields = { + circuit_mode_of_operation = { + fields = { + 'enable_disable', + 'send_to_train', + 'read_from_train', + 'read_stopped_train' + } + } + } + }, + transport_belt = { + fields = { + content_read_mode = { + fields = { + 'pulse', + 'hold' + } + } + } + }, + type = { + fields = { + 'container', + 'generic_on_off', + 'inserter', + 'lamp', + 'logistic_container', + 'roboport', + 'storage_tank', + 'train_stop', + 'decider_combinator', + 'arithmetic_combinator', + 'constant_combinator', + 'transport_belt', + 'accumulator', + 'rail_signal', + 'rail_chain_signal', + 'wall', + 'mining_drill', + 'programmable_speaker' + } + } + } + }, + controllers = { + fields = { + 'ghost', + 'character', + 'god', + 'editor', + 'cutscene', + 'spectator' + } + }, + deconstruction_item = { + fields = { + entity_filter_mode = { + fields = { + 'whitelist', + 'blacklist' + } + }, + tile_filter_mode = { + fields = { + 'whitelist', + 'blacklist' + } + }, + tile_selection_mode = { + fields = { + 'normal', + 'always', + 'never', + 'only' + } + } + } + }, + difficulty = { + fields = { + 'easy', + 'normal', + 'hard' + } + }, + difficulty_settings = { + fields = { + recipe_difficulty = { + fields = { + 'normal', + 'expensive' + } + }, + technology_difficulty = { + fields = { + 'normal', + 'expensive' + } + } + } + }, + direction = { + fields = { + 'north', + 'northeast', + 'east', + 'southeast', + 'south', + 'southwest', + 'west', + 'northwest' + } + }, + distraction = { + fields = { + 'by_enemy', + 'by_anything', + 'by_damage' + } + }, + entity_status = { + fields = { + 'working', + 'no_power', + 'no_fuel', + 'no_recipe', + 'no_input_fluid', + 'no_research_in_progress', + 'no_minable_resources', + 'low_input_fluid', + 'low_power', + 'disabled_by_control_behavior', + 'disabled_by_script', + 'fluid_ingredient_shortage', + 'fluid_production_overload', + 'item_ingredient_shortage', + 'item_production_overload', + 'marked_for_deconstruction', + 'missing_required_fluid', + 'missing_science_packs', + 'waiting_for_source_items', + 'waiting_for_space_in_destination', + 'waiting_to_launch_rocket' + } + }, + events = { + fields = { + 'on_tick', + 'on_gui_click', + 'on_gui_confirmed', + 'on_gui_text_changed', + 'on_gui_checked_state_changed', + 'on_entity_died', + 'on_post_entity_died', + 'on_entity_damaged', + 'on_picked_up_item', + 'on_built_entity', + 'on_sector_scanned', + 'on_player_mined_item', + 'on_put_item', + 'on_rocket_launched', + 'on_pre_player_mined_item', + 'on_chunk_generated', + 'on_player_crafted_item', + 'on_robot_built_entity', + 'on_robot_pre_mined', + 'on_robot_mined', + 'on_research_started', + 'on_research_finished', + 'on_player_rotated_entity', + 'on_player_set_quickbar_slot', + 'on_marked_for_deconstruction', + 'on_cancelled_deconstruction', + 'on_trigger_created_entity', + 'on_trigger_fired_artillery', + 'on_train_changed_state', + 'on_player_created', + 'on_resource_depleted', + 'on_player_driving_changed_state', + 'on_force_created', + 'on_forces_merging', + 'on_player_cursor_stack_changed', + 'on_pre_entity_settings_pasted', + 'on_entity_settings_pasted', + 'on_player_main_inventory_changed', + 'on_player_armor_inventory_changed', + 'on_player_ammo_inventory_changed', + 'on_player_gun_inventory_changed', + 'on_player_placed_equipment', + 'on_player_removed_equipment', + 'on_pre_player_died', + 'on_player_died', + 'on_player_respawned', + 'on_player_joined_game', + 'on_player_left_game', + 'on_player_built_tile', + 'on_player_mined_tile', + 'on_robot_built_tile', + 'on_robot_mined_tile', + 'on_player_selected_area', + 'on_player_alt_selected_area', + 'on_player_changed_surface', + 'on_selected_entity_changed', + 'on_market_item_purchased', + 'on_player_dropped_item', + 'on_biter_base_built', + 'on_player_changed_force', + 'on_entity_renamed', + 'on_gui_selection_state_changed', + 'on_runtime_mod_setting_changed', + 'on_difficulty_settings_changed', + 'on_surface_created', + 'on_surface_deleted', + 'on_pre_surface_deleted', + 'on_player_mined_entity', + 'on_robot_mined_entity', + 'on_train_created', + 'on_gui_elem_changed', + 'on_player_setup_blueprint', + 'on_player_deconstructed_area', + 'on_player_configured_blueprint', + 'on_console_chat', + 'on_console_command', + 'on_player_removed', + 'on_pre_player_removed', + 'on_player_used_capsule', + 'script_raised_built', + 'script_raised_destroy', + 'script_raised_revive', + 'on_player_promoted', + 'on_player_demoted', + 'on_combat_robot_expired', + 'on_player_changed_position', + 'on_mod_item_opened', + 'on_gui_opened', + 'on_gui_closed', + 'on_gui_value_changed', + 'on_player_muted', + 'on_player_unmuted', + 'on_player_cheat_mode_enabled', + 'on_player_cheat_mode_disabled', + 'on_character_corpse_expired', + 'on_pre_ghost_deconstructed', + 'on_player_pipette', + 'on_player_display_resolution_changed', + 'on_player_display_scale_changed', + 'on_pre_player_crafted_item', + 'on_player_cancelled_crafting', + 'on_chunk_charted', + 'on_technology_effects_reset', + 'on_land_mine_armed', + 'on_forces_merged', + 'on_player_trash_inventory_changed', + 'on_pre_player_left_game', + 'on_pre_surface_cleared', + 'on_surface_cleared', + 'on_chunk_deleted', + 'on_pre_chunk_deleted', + 'on_train_schedule_changed', + 'on_player_banned', + 'on_player_kicked', + 'on_player_unbanned', + 'on_rocket_launch_ordered', + 'on_script_path_request_finished', + 'on_ai_command_completed', + 'on_marked_for_upgrade', + 'on_cancelled_upgrade', + 'on_player_toggled_map_editor', + 'on_entity_cloned', + 'on_area_cloned', + 'on_brush_cloned', + 'on_game_created_from_scenario', + 'on_surface_imported', + 'on_surface_renamed', + 'on_player_toggled_alt_mode', + 'on_player_repaired_entity', + 'on_player_fast_transferred', + 'on_pre_robot_exploded_cliff', + 'on_robot_exploded_cliff', + 'on_entity_spawned', + 'on_cutscene_waypoint_reached', + 'on_unit_group_created', + 'on_unit_added_to_group', + 'on_unit_removed_from_group', + 'on_unit_group_finished_gathering', + 'on_build_base_arrived', + 'on_chart_tag_added', + 'on_chart_tag_modified', + 'on_chart_tag_removed', + 'on_lua_shortcut', + 'on_gui_location_changed', + 'on_gui_selected_tab_changed', + 'on_gui_switch_state_changed', + 'on_force_cease_fire_changed', + 'on_force_friends_changed', + 'on_string_translated', + 'on_script_trigger_effect' + } + }, + flow_precision_index = { + fields = { + 'one_second', + 'one_minute', + 'ten_minutes', + 'one_hour', + 'ten_hours', + 'fifty_hours', + 'two_hundred_fifty_hours', + 'one_thousand_hours' + } + }, + group_state = { + fields = { + 'gathering', + 'moving', + 'attacking_distraction', + 'attacking_target', + 'finished', + 'pathfinding', + 'wander_in_group' + } + }, + gui_type = { + fields = { + 'entity', + 'research', + 'controller', + 'production', + 'item', + 'bonus', + 'trains', + 'achievement', + 'blueprint_library', + 'equipment', + 'logistic', + 'other_player', + 'kills', + 'permissions', + 'tutorials', + 'custom', + 'server_management', + 'player_management', + 'tile' + } + }, + input_action = { + fields = { + 'activate_copy', + 'activate_cut', + 'activate_paste', + 'add_permission_group', + 'add_train_station', + 'admin_action', + 'alt_select_area', + 'alt_select_blueprint_entities', + 'alternative_copy', + 'begin_mining', + 'begin_mining_terrain', + 'build_item', + 'build_rail', + 'build_terrain', + 'cancel_craft', + 'cancel_deconstruct', + 'cancel_new_blueprint', + 'cancel_research', + 'cancel_upgrade', + 'change_active_item_group_for_crafting', + 'change_active_item_group_for_filters', + 'change_active_quick_bar', + 'change_arithmetic_combinator_parameters', + 'change_blueprint_book_record_label', + 'change_decider_combinator_parameters', + 'change_item_label', + 'change_multiplayer_config', + 'change_picking_state', + 'change_programmable_speaker_alert_parameters', + 'change_programmable_speaker_circuit_parameters', + 'change_programmable_speaker_parameters', + 'change_riding_state', + 'change_shooting_state', + 'change_single_blueprint_record_label', + 'change_train_stop_station', + 'change_train_wait_condition', + 'change_train_wait_condition_data', + 'clean_cursor_stack', + 'clear_selected_blueprint', + 'clear_selected_deconstruction_item', + 'clear_selected_upgrade_item', + 'connect_rolling_stock', + 'copy', + 'copy_entity_settings', + 'craft', + 'create_blueprint_like', + 'cursor_split', + 'cursor_transfer', + 'custom_input', + 'cycle_blueprint_book_backwards', + 'cycle_blueprint_book_forwards', + 'deconstruct', + 'delete_blueprint_library', + 'delete_blueprint_record', + 'delete_custom_tag', + 'delete_permission_group', + 'destroy_opened_item', + 'disconnect_rolling_stock', + 'drag_train_schedule', + 'drag_train_wait_condition', + 'drop_blueprint_record', + 'drop_item', + 'drop_to_blueprint_book', + 'edit_custom_tag', + 'edit_permission_group', + 'export_blueprint', + 'fast_entity_split', + 'fast_entity_transfer', + 'go_to_train_station', + 'grab_blueprint_record', + 'gui_checked_state_changed', + 'gui_click', + 'gui_confirmed', + 'gui_elem_changed', + 'gui_location_changed', + 'gui_selected_tab_changed', + 'gui_selection_state_changed', + 'gui_switch_state_changed', + 'gui_text_changed', + 'gui_value_changed', + 'import_blueprint', + 'import_blueprint_string', + 'import_permissions_string', + 'inventory_split', + 'inventory_transfer', + 'launch_rocket', + 'lua_shortcut', + 'map_editor_action', + 'market_offer', + 'mod_settings_changed', + 'open_achievements_gui', + 'open_blueprint_library_gui', + 'open_blueprint_record', + 'open_bonus_gui', + 'open_character_gui', + 'open_equipment', + 'open_gui', + 'open_item', + 'open_kills_gui', + 'open_logistic_gui', + 'open_mod_item', + 'open_production_gui', + 'open_technology_gui', + 'open_train_gui', + 'open_train_station_gui', + 'open_trains_gui', + 'open_tutorials_gui', + 'paste_entity_settings', + 'place_equipment', + 'quick_bar_pick_slot', + 'quick_bar_set_selected_page', + 'quick_bar_set_slot', + 'remove_cables', + 'remove_train_station', + 'reset_assembling_machine', + 'rotate_entity', + 'select_area', + 'select_blueprint_entities', + 'select_entity_slot', + 'select_item', + 'select_mapper_slot', + 'select_next_valid_gun', + 'select_tile_slot', + 'set_auto_launch_rocket', + 'set_autosort_inventory', + 'set_behavior_mode', + 'set_car_weapons_control', + 'set_circuit_condition', + 'set_circuit_mode_of_operation', + 'set_deconstruction_item_tile_selection_mode', + 'set_deconstruction_item_trees_and_rocks_only', + 'set_entity_color', + 'set_entity_energy_property', + 'set_filter', + 'set_heat_interface_mode', + 'set_heat_interface_temperature', + 'set_infinity_container_filter_item', + 'set_infinity_container_remove_unfiltered_items', + 'set_infinity_pipe_filter', + 'set_inserter_max_stack_size', + 'set_inventory_bar', + 'set_logistic_filter_item', + 'set_logistic_filter_signal', + 'set_logistic_trash_filter_item', + 'set_request_from_buffers', + 'set_research_finished_stops_game', + 'set_signal', + 'set_single_blueprint_record_icon', + 'set_splitter_priority', + 'set_train_stopped', + 'setup_assembling_machine', + 'setup_blueprint', + 'setup_single_blueprint_record', + 'smart_pipette', + 'stack_split', + 'stack_transfer', + 'start_repair', + 'start_research', + 'start_walking', + 'stop_building_by_moving', + 'switch_connect_to_logistic_network', + 'switch_constant_combinator_state', + 'switch_inserter_filter_mode_state', + 'switch_power_switch_state', + 'switch_to_rename_stop_gui', + 'take_equipment', + 'toggle_deconstruction_item_entity_filter_mode', + 'toggle_deconstruction_item_tile_filter_mode', + 'toggle_driving', + 'toggle_enable_vehicle_logistics_while_moving', + 'toggle_equipment_movement_bonus', + 'toggle_map_editor', + 'toggle_personal_roboport', + 'toggle_show_entity_info', + 'translate_string', + 'undo', + 'upgrade', + 'upgrade_opened_blueprint', + 'use_artillery_remote', + 'use_item', + 'wire_dragging', + 'write_to_console' + } + }, + inventory = { + fields = { + 'fuel', + 'burnt_result', + 'chest', + 'furnace_source', + 'furnace_result', + 'furnace_modules', + 'character_main', + 'character_guns', + 'character_ammo', + 'character_armor', + 'character_vehicle', + 'character_trash', + 'god_main', + 'editor_main', + 'editor_guns', + 'editor_ammo', + 'editor_armor', + 'roboport_robot', + 'roboport_material', + 'robot_cargo', + 'robot_repair', + 'assembling_machine_input', + 'assembling_machine_output', + 'assembling_machine_modules', + 'lab_input', + 'lab_modules', + 'mining_drill_modules', + 'item_main', + 'rocket_silo_rocket', + 'rocket_silo_result', + 'rocket', + 'car_trunk', + 'car_ammo', + 'cargo_wagon', + 'turret_ammo', + 'beacon_modules', + 'character_corpse', + 'artillery_turret_ammo', + 'artillery_wagon_ammo' + } + }, + logistic_member_index = { + fields = { + 'logistic_container', + 'vehicle_storage', + 'character_requester', + 'character_storage', + 'character_provider', + 'generic_on_off_behavior' + } + }, + logistic_mode = { + fields = { + 'active_provider', + 'storage', + 'requester', + 'passive_provider', + 'buffer' + } + }, + mouse_button_type = { + fields = { + 'left', + 'right', + 'middle' + } + }, + rail_connection_direction = { + fields = { + 'left', + 'straight', + 'right' + } + }, + rail_direction = { + fields = { + 'front', + 'back' + } + }, + render_mode = { + fields = { + 'game', + 'chart', + 'chart_zoomed_in' + } + }, + rich_text_setting = { + fields = { + 'enabled', + 'disabled', + 'highlight' + } + }, + riding = { + fields = { + acceleration = { + fields = { + 'nothing', + 'accelerating', + 'braking', + 'reversing' + } + }, + direction = { + fields = { + 'left', + 'straight', + 'right' + } + } + } + }, + shooting = { + fields = { + 'not_shooting', + 'shooting_enemies', + 'shooting_selected' + } + }, + signal_state = { + fields = { + 'open', + 'closed', + 'reserved', + 'reserved_by_circuit_network' + } + }, + train_state = { + fields = { + 'on_the_path', + 'path_lost', + 'no_schedule', + 'no_path', + 'arrive_signal', + 'wait_signal', + 'arrive_station', + 'wait_station', + 'manual_control_stop', + 'manual_control' + } + }, + transport_line = { + fields = { + 'left_line', + 'right_line', + 'left_underground_line', + 'right_underground_line', + 'secondary_left_line', + 'secondary_right_line', + 'left_split_line', + 'right_split_line', + 'secondary_left_split_line', + 'secondary_right_split_line' + } + }, + wire_connection_id = { + fields = { + 'electric_pole', + 'power_switch_left', + 'power_switch_right' + } + }, + wire_type = { + fields = { + 'red', + 'green', + 'copper' + } + }, + -- Defines additional modules + color = { + other_fields = true + }, + anticolor = { + other_fields = true + }, + lightcolor = { + other_fields = true + }, + time = { + fields = { + 'second', + 'minute', + 'hour', + 'day', + 'week', + 'month', + 'year' + } + } + } + } + } + } +end + +--[[ Options "ignore", "std", "globals", "unused_args", "self", "compat", "global", "unused", "redefined", "unused_secondaries", "allow_defined", "allow_defined_top", "module", "read_globals", "new_globals", "new_read_globals", "enable", "only", "not_globals", @@ -949,54 +1643,55 @@ stds.factorio_defines = { "max_cyclomatic_complexity" --]] --- Warnings list --- 011 A syntax error. --- 021 An invalid inline option. --- 022 An unpaired inline push directive. --- 023 An unpaired inline pop directive. --- 111 Setting an undefined global variable. --- 112 Mutating an undefined global variable. --- 113 Accessing an undefined global variable. --- 121 Setting a read-only global variable. --- 122 Setting a read-only field of a global variable. --- 131 Unused implicitly defined global variable. --- 142 Setting an undefined field of a global variable. --- 143 Accessing an undefined field of a global variable. --- 211 Unused local variable. --- 212 Unused argument. --- 213 Unused loop variable. --- 221 Local variable is accessed but never set. --- 231 Local variable is set but never accessed. --- 232 An argument is set but never accessed. --- 233 Loop variable is set but never accessed. --- 241 Local variable is mutated but never accessed. --- 311 Value assigned to a local variable is unused. --- 312 Value of an argument is unused. --- 313 Value of a loop variable is unused. --- 314 Value of a field in a table literal is unused. --- 321 Accessing uninitialized local variable. --- 331 Value assigned to a local variable is mutated but never accessed. --- 341 Mutating uninitialized local variable. --- 411 Redefining a local variable. --- 412 Redefining an argument. --- 413 Redefining a loop variable. --- 421 Shadowing a local variable. --- 422 Shadowing an argument. --- 423 Shadowing a loop variable. --- 431 Shadowing an upvalue. --- 432 Shadowing an upvalue argument. --- 433 Shadowing an upvalue loop variable. --- 511 Unreachable code. --- 512 Loop can be executed at most once. --- 521 Unused label. --- 531 Left-hand side of an assignment is too short. --- 532 Left-hand side of an assignment is too long. --- 541 An empty do end block. --- 542 An empty if branch. --- 551 An empty statement. --- 611 A line consists of nothing but whitespace. --- 612 A line contains trailing whitespace. --- 613 Trailing whitespace in a string. --- 614 Trailing whitespace in a comment. --- 621 Inconsistent indentation (SPACE followed by TAB). --- 631 Line is too long. +--[[ Warnings list + -- 011 A syntax error. + -- 021 An invalid inline option. + -- 022 An unpaired inline push directive. + -- 023 An unpaired inline pop directive. + -- 111 Setting an undefined global variable. + -- 112 Mutating an undefined global variable. + -- 113 Accessing an undefined global variable. + -- 121 Setting a read-only global variable. + -- 122 Setting a read-only field of a global variable. + -- 131 Unused implicitly defined global variable. + -- 142 Setting an undefined field of a global variable. + -- 143 Accessing an undefined field of a global variable. + -- 211 Unused local variable. + -- 212 Unused argument. + -- 213 Unused loop variable. + -- 221 Local variable is accessed but never set. + -- 231 Local variable is set but never accessed. + -- 232 An argument is set but never accessed. + -- 233 Loop variable is set but never accessed. + -- 241 Local variable is mutated but never accessed. + -- 311 Value assigned to a local variable is unused. + -- 312 Value of an argument is unused. + -- 313 Value of a loop variable is unused. + -- 314 Value of a field in a table literal is unused. + -- 321 Accessing uninitialized local variable. + -- 331 Value assigned to a local variable is mutated but never accessed. + -- 341 Mutating uninitialized local variable. + -- 411 Redefining a local variable. + -- 412 Redefining an argument. + -- 413 Redefining a loop variable. + -- 421 Shadowing a local variable. + -- 422 Shadowing an argument. + -- 423 Shadowing a loop variable. + -- 431 Shadowing an upvalue. + -- 432 Shadowing an upvalue argument. + -- 433 Shadowing an upvalue loop variable. + -- 511 Unreachable code. + -- 512 Loop can be executed at most once. + -- 521 Unused label. + -- 531 Left-hand side of an assignment is too short. + -- 532 Left-hand side of an assignment is too long. + -- 541 An empty do end block. + -- 542 An empty if branch. + -- 551 An empty statement. + -- 611 A line consists of nothing but whitespace. + -- 612 A line contains trailing whitespace. + -- 613 Trailing whitespace in a string. + -- 614 Trailing whitespace in a comment. + -- 621 Inconsistent indentation (SPACE followed by TAB). + -- 631 Line is too long. +--]] diff --git a/Factorio-luacheckrc b/Factorio-luacheckrc index 0c0518d1..53d12a83 160000 --- a/Factorio-luacheckrc +++ b/Factorio-luacheckrc @@ -1 +1 @@ -Subproject commit 0c0518d165b0fcee714f9e00b014afd7aba9fbee +Subproject commit 53d12a834fe0657e4be17df67a93c51af4e3981e From effae90ff1471532a61790061f0cb63bca7fac18 Mon Sep 17 00:00:00 2001 From: Bastiaan Date: Sun, 22 Mar 2020 23:47:48 +0100 Subject: [PATCH 47/81] Fix Issue #149 Filtered out gui elements without Gui.define --- expcore/gui/prototype.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 3c648c31..21ee907c 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -349,6 +349,7 @@ local function event_handler_factory(event_name) local element = event.element if not element or not element.valid then return end local element_define = Gui.defines[element.name] + if not element_define then return end element_define:raise_custom_event(event) end) @@ -411,4 +412,4 @@ Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) -- Module return -return Gui \ No newline at end of file +return Gui From c9b704b9a094e7efb5bca2b06ac92a2c2cd4983b Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 23 Mar 2020 18:03:29 +0000 Subject: [PATCH 48/81] Working center gui --- config/_file_loader.lua | 1 + config/roles.lua | 3 +- expcore/gui/left_flow.lua | 41 +++---------------------- expcore/gui/prototype.lua | 4 +-- expcore/gui/top_flow.lua | 63 +++++++++++++++++++++++++++++++++++++++ modules/gui/readme.lua | 49 ++++++++++++++++++++++++++++++ 6 files changed, 121 insertions(+), 40 deletions(-) create mode 100644 modules/gui/readme.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 35a07946..0a5ed1df 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -43,6 +43,7 @@ return { 'modules.addons.chat-reply', 'modules.addons.tree-decon', -- GUI + 'modules.gui.readme', 'modules.gui.rocket-info', 'modules.gui.science-info', 'modules.gui.warp-list', diff --git a/config/roles.lua b/config/roles.lua index ff40131f..800d4cf1 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -220,7 +220,8 @@ local default = Roles.new_role('Guest','') 'gui/rocket-info', 'gui/science-info', 'gui/task-list', - 'gui/warp-list' + 'gui/warp-list', + 'gui/readme' } --- Jail role diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index f41d8419..03fba9ab 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -42,28 +42,6 @@ function Gui._prototype_element:add_to_left_flow(open_on_join) return self end ---[[-- Styles a top flow button depending on the state given -@tparam LuaGuiElement the button element to style -@tparam boolean state The state the button is in - -@usage-- Sets the button to the visible style -Gui.left_toolbar_button_style(button, true) - -@usage-- Sets the button to the hidden style -Gui.left_toolbar_button_style(button, false) - -]] -function Gui.left_toolbar_button_style(button, state) - if state then - button.style = Gui.top_flow_button_visible_style - else - button.style = Gui.top_flow_button_style - end - button.style.minimal_width = 36 - button.style.height = 36 - button.style.padding = -2 -end - --[[-- Creates a button on the top flow which will toggle the given element define, the define must exist in the left flow @tparam string sprite the sprite that you want to use on the button @tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have @@ -78,18 +56,7 @@ end) ]] function Gui.left_toolbar_button(sprite,tooltip,element_define,authenticator) - local button = Gui.element{ - type = 'sprite-button', - sprite = sprite, - tooltip = tooltip, - style = Gui.top_flow_button_style - } - :style{ - minimal_width = 36, - height = 36, - padding = -2 - } - :add_to_top_flow(authenticator) + local button = Gui.toolbar_button(sprite,tooltip,authenticator) -- Add on_click handler to handle click events comming from the player button:on_click(function(player,_,_) @@ -152,7 +119,7 @@ function Gui.draw_left_flow(player) local button = top_flow[element_define.toolbar_button] if button then -- Style the button - Gui.left_toolbar_button_style(button, visible) + Gui.toolbar_button_style(button, visible) end end end @@ -206,7 +173,7 @@ function Gui.hide_left_flow(player) local button = top_flow[element_define.toolbar_button] if button then -- Style the button - Gui.left_toolbar_button_style(button, false) + Gui.toolbar_button_style(button, false) -- Get the button define from the reverse lookup on the element local button_define = Gui.defines[element_define.toolbar_button] -- Raise the custom event if all of the top checks have passed @@ -263,7 +230,7 @@ function Gui.toggle_left_element(player,element_define,state) local button = top_flow[element_define.toolbar_button] if button then -- Style the button - Gui.left_toolbar_button_style(button, state) + Gui.toolbar_button_style(button, state) end end return state diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 21ee907c..526d27b0 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -365,11 +365,11 @@ end --- Called when the player opens a GUI. -- @tparam function handler the event handler which will be called -Gui._prototype_element.on_opened = event_handler_factory(defines.events.on_gui_opened) +Gui._prototype_element.on_open = event_handler_factory(defines.events.on_gui_opened) --- Called when the player closes the GUI they have open. -- @tparam function handler the event handler which will be called -Gui._prototype_element.on_closed = event_handler_factory(defines.events.on_gui_closed) +Gui._prototype_element.on_close = event_handler_factory(defines.events.on_gui_closed) --- Called when LuaGuiElement is clicked. -- @tparam function handler the event handler which will be called diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua index d9291d0f..f06dea2e 100644 --- a/expcore/gui/top_flow.lua +++ b/expcore/gui/top_flow.lua @@ -101,4 +101,67 @@ function Gui.toggle_top_flow(player,state) top_flow.visible = state return state +end + +--[[-- Get the element define that is in the top flow, use in events without an element refrence +@tparam LuaPlayer player the player that you want to get the element for +@tparam table element_define the element that you want to get +@treturn LuaGuiElement the gui element linked to this define for this player + +@usage-- Get your top element +local button = Gui.get_top_element(game.player, example_button) + +]] +function Gui.get_top_element(player, element_define) + local top_flow = Gui.get_top_flow(player) + return top_flow[element_define.name] +end + +--[[-- Creates a button on the top flow with consistent styling +@tparam string sprite the sprite that you want to use on the button +@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have +@tparam[opt] function authenticator used to decide if the button should be visible to a player + +@usage-- Add a button to the toolbar +local toolbar_button = +Gui.left_toolbar_button('entity/inserter', 'Nothing to see here', function(player) + return player.admin +end) + +]] +function Gui.toolbar_button(sprite,tooltip,authenticator) + return Gui.element{ + type = 'sprite-button', + sprite = sprite, + tooltip = tooltip, + style = Gui.top_flow_button_style + } + :style{ + minimal_width = 36, + height = 36, + padding = -2 + } + :add_to_top_flow(authenticator) +end + +--[[-- Styles a top flow button depending on the state given +@tparam LuaGuiElement the button element to style +@tparam boolean state The state the button is in + +@usage-- Sets the button to the visible style +Gui.toolbar_button_style(button, true) + +@usage-- Sets the button to the hidden style +Gui.toolbar_button_style(button, false) + +]] +function Gui.toolbar_button_style(button, state) + if state then + button.style = Gui.top_flow_button_visible_style + else + button.style = Gui.top_flow_button_style + end + button.style.minimal_width = 36 + button.style.height = 36 + button.style.padding = -2 end \ No newline at end of file diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua new file mode 100644 index 00000000..c66bee57 --- /dev/null +++ b/modules/gui/readme.lua @@ -0,0 +1,49 @@ +--[[-- Gui Module - Readme + - Adds a main gui that contains lots of important information about our server + @gui Readme + @alias readme +]] + +local Gui = require 'expcore.gui' --- @dep expcore.gui +local Roles = require 'expcore.roles' --- @dep expcore.roles +local Event = require 'utils.event' --- @dep utils.event +local Game = require 'utils.game' --- @dep utils.game + +--- Main readme container for the center flow +-- @element readme +local readme_toggle +local readme = +Gui.element(function(event_trigger,parent) + local container = Gui.container(parent,event_trigger,200) + return container.parent +end) +:on_open(function(player) + local toggle_button = Gui.get_top_element(player, readme_toggle) + Gui.toolbar_button_style(toggle_button, true) +end) +:on_close(function(player,element) + local toggle_button = Gui.get_top_element(player, readme_toggle) + Gui.toolbar_button_style(toggle_button, false) + Gui.destroy_if_valid(element) +end) + +--- Toggle button for the readme gui +-- @element readme_toggle +readme_toggle = +Gui.toolbar_button('virtual-signal/signal-info','Readme',function(player) + return Roles.player_allowed(player,'gui/readme') +end) +:on_click(function(player,element) + local center = player.gui.center + if center[readme.name] then + player.opened = nil + else + player.opened = readme(center) + end +end) + +--- When a player joins the game for the first time show this gui +Event.add(defines.events.on_player_created,function(event) + local player = Game.get_player_by_index(event.player_index) + player.opened = readme(player.gui.center) +end) \ No newline at end of file From 162d586b34e4d8893bdbfaa37a9c45627cce4f1d Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 23 Mar 2020 20:25:07 +0000 Subject: [PATCH 49/81] Frame layout complete --- modules/gui/readme.lua | 97 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index c66bee57..d94890c2 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -9,13 +9,90 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game +local tabs = {} +local function Tab(caption,tooltip,element_define) + tabs[#tabs+1] = {caption,tooltip,element_define} +end + +--- Content area for the welcome tab +-- @element welcome_content +Tab('Welcome',nil, +Gui.element{ + type = 'label', + caption = 'Welcome' +}) + +--- Content area for the rules tab +-- @element rules_content +Tab('Rules',nil, +Gui.element{ + type = 'label', + caption = 'Rules' +}) + +--- Content area for the commands tab +-- @element commands_content +Tab('Commands',nil, +Gui.element{ + type = 'label', + caption = 'Commands' +}) + +--- Content area for the servers tab +-- @element servers_content +Tab('Servers',nil, +Gui.element{ + type = 'label', + caption = 'Servers' +}) + +--- Content area for the servers tab +-- @element servers_content +Tab('Backers',nil, +Gui.element{ + type = 'label', + caption = 'Backers' +}) + --- Main readme container for the center flow -- @element readme local readme_toggle local readme = Gui.element(function(event_trigger,parent) - local container = Gui.container(parent,event_trigger,200) - return container.parent + local container = parent.add{ + name = event_trigger, + type = 'frame', + style = 'invisible_frame' + } + + -- Add the left hand side of the frame back, removed because of frame_tabbed_pane style + local left_lignment = Gui.alignment(container,nil,nil,'bottom') + left_lignment.style.padding = {32,0,0,0} + + local left_side = + left_lignment.add{ + type = 'frame', + style = 'frame_without_right_side' + } + left_side.style.vertically_stretchable = true + left_side.style.padding = 0 + left_side.style.width = 5 + + -- Add the tab pane + local tab_pane = container.add{ + name = 'pane', + type = 'tabbed-pane', + style = 'frame_tabbed_pane' + } + + -- Add the different content areas + for _,tab_details in ipairs(tabs) do + local tab = tab_pane.add{ type = 'tab', style = 'frame_tab', caption = tab_details[1], tooltip = tab_details[2] } + tab_pane.add_tab(tab, tab_details[3](tab_pane)) + end + + tab_pane.style.width = 500 + return container end) :on_open(function(player) local toggle_button = Gui.get_top_element(player, readme_toggle) @@ -30,10 +107,10 @@ end) --- Toggle button for the readme gui -- @element readme_toggle readme_toggle = -Gui.toolbar_button('virtual-signal/signal-info','Readme',function(player) +Gui.toolbar_button('virtual-signal/signal-info','Information',function(player) return Roles.player_allowed(player,'gui/readme') end) -:on_click(function(player,element) +:on_click(function(player,_) local center = player.gui.center if center[readme.name] then player.opened = nil @@ -45,5 +122,15 @@ end) --- When a player joins the game for the first time show this gui Event.add(defines.events.on_player_created,function(event) local player = Game.get_player_by_index(event.player_index) - player.opened = readme(player.gui.center) + local element = readme(player.gui.center) + element.pane.selected_tab_index = 1 + player.opened = element +end) + +--- When a player joins clear center unless the player has something open +Event.add(defines.events.on_player_joined_game,function(event) + local player = Game.get_player_by_index(event.player_index) + if not player.opened then + player.gui.center.clear() + end end) \ No newline at end of file From 53ec32c832d69326e6e60d30b7b0834f14528cdb Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 24 Mar 2020 18:41:57 +0000 Subject: [PATCH 50/81] Added welcome tab --- config/join_messages.lua | 4 +- expcore/gui/defines.lua | 24 +++++++++++ locale/en/gui.cfg | 16 +++++++ modules/gui/logo.png | Bin 0 -> 15942 bytes modules/gui/readme.lua | 88 +++++++++++++++++++++++++++++++++------ 5 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 modules/gui/logo.png diff --git a/config/join_messages.lua b/config/join_messages.lua index 058435d3..b0226a28 100644 --- a/config/join_messages.lua +++ b/config/join_messages.lua @@ -2,5 +2,7 @@ return { Cooldude2606 = 'Lua lets you set metatables on numbers, did you know that? Cooldude2606 knows this.', samy115 = 'Tremble in fear as the banhammer is now here, its owner: samy115', XenoCyber = '"Fire Fire Fire" oops wrong game, have no fear XenoCyber is here', - HunterOfGames = 'Unable to support HunterOfGames. You must construct additional miners.' + HunterOfGames = 'Unable to support HunterOfGames. You must construct additional miners.', + ookl = 'ookl says: "Pineapples are amazing, hello everyone!"', + arty714 = 'Arty\'s Potato made it!' } \ No newline at end of file diff --git a/expcore/gui/defines.lua b/expcore/gui/defines.lua index d062078c..41af4c32 100644 --- a/expcore/gui/defines.lua +++ b/expcore/gui/defines.lua @@ -215,4 +215,28 @@ end) local frame_style = element.parent.style frame_style.padding = 2 frame_style.minimal_width = width +end) + +--[[-- Used to make a solid white bar in a gui +@element Gui.bar +@tparam LuaGuiElement parent the parent element to which the container will be added +@tparam number width the width of the bar that will be made, if not given bar will strech to fill the parent + +@usage-- Adding a bar to a gui +local bar = Gui.bar(parent, 100) + +]] +Gui.bar = +Gui.element(function(_,parent) + return parent.add{ + type = 'progressbar', + size = 1, + value = 1 + } +end) +:style(function(style,_,width) + style.height = 3 + style.color = {r=255,g=255,b=255} + if width then style.width = width + else style.horizontally_stretchable = true end end) \ No newline at end of file diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 440f485d..44ff5d20 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -97,3 +97,19 @@ timer-tooltip=Warp cooldown takes __1__ seconds goto-tooltip=Go to x __1__ y __2__ goto-disabled=You must be on a warp point and have a full charge to warp goto-edit=Edit warp icon + +[readme] +main-tooltip=Infomation +welcome-tab=Welcome +welcome-tooltip=Welcome to Explosive Gaming +welcome-general=Welcome to Explosive Gaming, we host many factorio servers. While you are here we require you to follow our rules, you can find these in the tab above. You can also find our custom commands and links to our other servers.\nPlease note that our servers reset periodically, the next reset is: __1__ +welcome-roles=We run a custom role system to help protect the work of others. As a result you may not be able to use your deconstruction planner yet or drop item on the groud. Roles also give you access to some custom features such as adding tasks to our task list or making new warp points.\nYou have been assigned the roles: __1__ +welcome-chat=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.\nThe setting you need to change is “Toggle chat (and Lua console)” you currently have it set to "__CONTROL__toggle-console__" +rules-tab=Rules +rules-tooltip=Rules for our server +commands-tab=Commands +commands-tooltip=Commands which you are able to use +servers-tab=Servers +servers-tooltip=Links to our other servers and sites +backers-tab=Backers +backers-tooltip=People who have helped make our server \ No newline at end of file diff --git a/modules/gui/logo.png b/modules/gui/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..cef59c4d1f82ada58092f1d64480c7e8df6ced72 GIT binary patch literal 15942 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 o01M!IZ=>wJ@ literal 0 HcmV?d00001 diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index d94890c2..2fe865e4 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -14,17 +14,82 @@ local function Tab(caption,tooltip,element_define) tabs[#tabs+1] = {caption,tooltip,element_define} end +local function description_label(parent,width,caption) + local label = parent.add{ + type = 'label', + caption = caption, + style = 'description_label' + } + + local style = label.style + style.horizontal_align = 'center' + style.single_line = false + style.width = width +end + +--- Sub content area used within the content areas +-- @element sub_content +local sub_content = +Gui.element(function(_,parent) + return parent.add{ + type = 'frame', + direction = 'vertical', + style = 'image_frame' + } +end) +:style{ + horizontally_stretchable = true, + horizontal_align = 'center' +} + --- Content area for the welcome tab -- @element welcome_content -Tab('Welcome',nil, -Gui.element{ - type = 'label', - caption = 'Welcome' -}) +Tab({'readme.welcome-tab'},{'readme.welcome-tooltip'}, +Gui.element(function(_,parent) + local server_details = global.server_details or { name='ExpGaming S0 - Local', description='Failed to load description: disconnected from sync api.', reset_time='Non Set', branch='Unknown'} + local container = parent.add{ type='flow', direction='vertical' } + local player = Gui.get_player_from_element(parent) + + -- Set up the top flow with logos + local top_flow = container.add{ type='flow' } + top_flow.add{ type='sprite', sprite='file/modules/gui/logo.png'} + local top_vertical_flow = top_flow.add{ type='flow', direction='vertical' } + top_flow.add{ type='sprite', sprite='file/modules/gui/logo.png'} + top_vertical_flow.style.horizontal_align = 'center' + + -- Add the title to the top flow + local title_flow = top_vertical_flow.add{ type='flow' } + title_flow.style.vertical_align = 'center' + Gui.bar(title_flow,85) + title_flow.add{ + type = 'label', + caption = 'Welcome to '..server_details.name, + style = 'caption_label' + } + Gui.bar(title_flow,85) + + -- Add the description to the top flow + description_label(top_vertical_flow,380,server_details.description) + Gui.bar(container) + + -- Get the names of the roles the player has + local player_roles = Roles.get_player_roles(player) + local role_names = {} + for i,role in ipairs(player_roles) do + role_names[i] = role.name + end + + -- Add the other information to the gui + description_label(sub_content(container),575,{'readme.welcome-general',server_details.reset_time}) + description_label(sub_content(container),575,{'readme.welcome-roles',table.concat(role_names,', ')}) + description_label(sub_content(container),575,{'readme.welcome-chat'}) + + return container +end)) --- Content area for the rules tab -- @element rules_content -Tab('Rules',nil, +Tab({'readme.rules-tab'},{'readme.rules-tooltip'}, Gui.element{ type = 'label', caption = 'Rules' @@ -32,7 +97,7 @@ Gui.element{ --- Content area for the commands tab -- @element commands_content -Tab('Commands',nil, +Tab({'readme.commands-tab'},{'readme.commands-tooltip'}, Gui.element{ type = 'label', caption = 'Commands' @@ -40,15 +105,15 @@ Gui.element{ --- Content area for the servers tab -- @element servers_content -Tab('Servers',nil, +Tab({'readme.servers-tab'},{'readme.servers-tooltip'}, Gui.element{ type = 'label', caption = 'Servers' }) --- Content area for the servers tab --- @element servers_content -Tab('Backers',nil, +-- @element backers_content +Tab({'readme.backers-tab'},{'readme.backers-tooltip'}, Gui.element{ type = 'label', caption = 'Backers' @@ -91,7 +156,6 @@ Gui.element(function(event_trigger,parent) tab_pane.add_tab(tab, tab_details[3](tab_pane)) end - tab_pane.style.width = 500 return container end) :on_open(function(player) @@ -107,7 +171,7 @@ end) --- Toggle button for the readme gui -- @element readme_toggle readme_toggle = -Gui.toolbar_button('virtual-signal/signal-info','Information',function(player) +Gui.toolbar_button('virtual-signal/signal-info',{'readme.main-tooltip'},function(player) return Roles.player_allowed(player,'gui/readme') end) :on_click(function(player,_) From e493b573fb2fb737a7db3da272a454ced9c32ca7 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 24 Mar 2020 19:43:49 +0000 Subject: [PATCH 51/81] Added rules tab --- locale/en/gui.cfg | 16 ++++++++++++++++ modules/gui/readme.lua | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 44ff5d20..ab9c6df9 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -107,6 +107,22 @@ welcome-roles=We run a custom role system to help protect the work of others. As welcome-chat=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.\nThe setting you need to change is “Toggle chat (and Lua console)” you currently have it set to "__CONTROL__toggle-console__" rules-tab=Rules rules-tooltip=Rules for our server +rules-general=By playing on our servers you accept the rules below. If you are supected of breaking a rule then you will be questioned by one of our moderators. If required you will be banned from our servers, appeals can be made by contacting an Administrator on our discord. +rules-1=Hacking / cheating / abusing bugs will not be tolerated. +rules-2=Any bugs or exploits found should be reported to our staff members. +rules-3=Be respectful to other players in chat, this includes any other forms of communication. +rules-4=Taking all items from a belt or logistics network is forbidden: sharing resources is mandatory. +rules-5=Spamming of chat, bots, unlimited chests, or concrete is not allowed. +rules-6=Before removing major parts of the factory tell other players why you are removing it. +rules-7=Do not cause unnecessary lag by placing/removing tiles with bots or using active provider chests, if think some thing might cause lag please ask staff first. +rules-8=Do not walk in random directions with no reason, this is to reduce map download times. +rules-9=Do not use speakers on global or with alerts without prior permission, no one wants to hear your music at full volume without knowing where the off switch is. +rules-10=Do not rotate belts, deactivate belts with wires, or cause production to stop without good reason, this goes for inserters and spliters as well. +rules-11=Do not make train roundabouts. Other loops such as RoRo stations are allowed. +rules-12=When using trains, use the same size other players have used, many players use 1-2-1, 2-4-2, or 3-8-3, meaning 1 engine 2 cargo 1 engine. +rules-13=Trains are Left Hand Drive (LHD) only, this means trains drive on the left side of the tracks. +rules-14=Do not beg for roles, advertise other servers, or link to harmful sites. +rules-15=Use common sense, report rule breakers, and Administrators have the final word. commands-tab=Commands commands-tooltip=Commands which you are able to use servers-tab=Servers diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index 2fe865e4..a0470a62 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -90,10 +90,36 @@ end)) --- Content area for the rules tab -- @element rules_content Tab({'readme.rules-tab'},{'readme.rules-tooltip'}, -Gui.element{ - type = 'label', - caption = 'Rules' -}) +Gui.element(function(_,parent) + local container = parent.add{ type='flow', direction='vertical' } + + -- Add the title to the content + local title_flow = container.add{ type='flow' } + title_flow.style.vertical_align = 'center' + Gui.bar(title_flow,267) + title_flow.add{ + type = 'label', + caption = {'readme.rules-tab'}, + style = 'heading_1_label' + } + Gui.bar(title_flow,267) + + -- Add the tab description + description_label(container,575,{'readme.rules-general'}) + Gui.bar(container) + + -- Add a table for the rules + local rules = Gui.scroll_table(container,275,1) + rules.style = 'bordered_table' + rules.style.top_margin = 2 + + -- Add the rules to the table + for i = 1,15 do + description_label(rules,545,{'readme.rules-'..i}) + end + + return container +end)) --- Content area for the commands tab -- @element commands_content From 8362e5a3976a13ebead2c6ee0d24434dcaac79bf Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 25 Mar 2020 21:18:03 +0000 Subject: [PATCH 52/81] Added commands tab --- config/roles.lua | 2 +- locale/en/commands.cfg | 6 ++-- locale/en/gui.cfg | 1 + modules/commands/help.lua | 3 +- modules/gui/readme.lua | 70 +++++++++++++++++++++++++-------------- 5 files changed, 53 insertions(+), 29 deletions(-) diff --git a/config/roles.lua b/config/roles.lua index 800d4cf1..8361be53 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -211,7 +211,7 @@ local default = Roles.new_role('Guest','') :allow{ 'command/tag', 'command/tag-clear', - 'command/chelp', + 'command/search-help', 'command/list-roles', 'command/find-on-map', 'command/report', diff --git a/locale/en/commands.cfg b/locale/en/commands.cfg index ab475d4b..4a68fc4f 100644 --- a/locale/en/commands.cfg +++ b/locale/en/commands.cfg @@ -10,7 +10,7 @@ to-self=Player can not be teleported to themselves. [expcom-chelp] title=Help results for "__1__": -footer=[__1__ results found; page __2__ of __3__] +footer=[__1__ results found: page __2__ of __3__] format=/__1__ __2__ - __3__ __4__ alias=Alias: __1__ out-of-range=__1__ is an invalid page number. @@ -61,8 +61,8 @@ wip=This command is temporary and will be replaced at some point in the future. [expcom-ratio] notSelecting=Please select an entetiy with a recpie. -item-in=You need __1__ per seconds of [item=__2__]. -fluid-in=You need __1__ per seconds of [fluid=__2__]. +item-in=You need __1__ per second of [item=__2__]. +fluid-in=You need __1__ per second of [fluid=__2__]. item-out=This will result in: __1__ [item=__2__] per second. fluid-out=This will result in: __1__ [fluid=__2__] per second. machines=And you will need __1__ machines (with the same speed as this one) for this. diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index ab9c6df9..f7217991 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -125,6 +125,7 @@ rules-14=Do not beg for roles, advertise other servers, or link to harmful sites rules-15=Use common sense, report rule breakers, and Administrators have the final word. commands-tab=Commands commands-tooltip=Commands which you are able to use +commands-general=We have lots of custom commands which you are able to use. Below you can find a list of all the commands that you are allowed to use and what they do. If you need more information or want to search for a command you can use our /search-help command. servers-tab=Servers servers-tooltip=Links to our other servers and sites backers-tab=Backers diff --git a/modules/commands/help.lua b/modules/commands/help.lua index 92904650..62dac168 100644 --- a/modules/commands/help.lua +++ b/modules/commands/help.lua @@ -18,7 +18,8 @@ end) -- @command chelp -- @tparam string keyword the keyword that will be looked for -- @tparam number page the page of help to view, must be in range of pages -Commands.new_command('chelp','Searches for a keyword in all commands you are allowed to use.') +Commands.new_command('search-help','Searches for a keyword in all commands you are allowed to use.') +:add_alias('chelp','shelp','commands') :add_param('keyword',true) :add_param('page',true,'integer') :set_defaults{keyword='',page=1} diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index a0470a62..b969b113 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -6,6 +6,7 @@ local Gui = require 'expcore.gui' --- @dep expcore.gui local Roles = require 'expcore.roles' --- @dep expcore.roles +local Commands = require 'expcore.commands' --- @dep expcore.commands local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game @@ -42,6 +43,24 @@ end) horizontal_align = 'center' } +--- Title element with bars on each side +-- @element title +local title = +Gui.element(function(_,parent,bar_size,caption) + local title_flow = parent.add{ type='flow' } + title_flow.style.vertical_align = 'center' + + Gui.bar(title_flow,bar_size) + local title_label = title_flow.add{ + type = 'label', + caption = caption, + style = 'heading_1_label' + } + Gui.bar(title_flow) + + return title_label +end) + --- Content area for the welcome tab -- @element welcome_content Tab({'readme.welcome-tab'},{'readme.welcome-tooltip'}, @@ -58,15 +77,7 @@ Gui.element(function(_,parent) top_vertical_flow.style.horizontal_align = 'center' -- Add the title to the top flow - local title_flow = top_vertical_flow.add{ type='flow' } - title_flow.style.vertical_align = 'center' - Gui.bar(title_flow,85) - title_flow.add{ - type = 'label', - caption = 'Welcome to '..server_details.name, - style = 'caption_label' - } - Gui.bar(title_flow,85) + title(top_vertical_flow,62,'Welcome to '..server_details.name) -- Add the description to the top flow description_label(top_vertical_flow,380,server_details.description) @@ -94,28 +105,20 @@ Gui.element(function(_,parent) local container = parent.add{ type='flow', direction='vertical' } -- Add the title to the content - local title_flow = container.add{ type='flow' } - title_flow.style.vertical_align = 'center' - Gui.bar(title_flow,267) - title_flow.add{ - type = 'label', - caption = {'readme.rules-tab'}, - style = 'heading_1_label' - } - Gui.bar(title_flow,267) + title(container,267,{'readme.rules-tab'}) -- Add the tab description description_label(container,575,{'readme.rules-general'}) Gui.bar(container) -- Add a table for the rules + container.add{ type='flow' } local rules = Gui.scroll_table(container,275,1) rules.style = 'bordered_table' - rules.style.top_margin = 2 -- Add the rules to the table for i = 1,15 do - description_label(rules,545,{'readme.rules-'..i}) + description_label(rules,555,{'readme.rules-'..i}) end return container @@ -124,11 +127,30 @@ end)) --- Content area for the commands tab -- @element commands_content Tab({'readme.commands-tab'},{'readme.commands-tooltip'}, -Gui.element{ - type = 'label', - caption = 'Commands' -}) +Gui.element(function(_,parent) + local container = parent.add{ type='flow', direction='vertical' } + local player = Gui.get_player_from_element(parent) + -- Add the title to the content + title(container,250,{'readme.commands-tab'}) + + -- Add the tab description + description_label(container,575,{'readme.commands-general'}) + Gui.bar(container) + + -- Add a table for the rules + container.add{ type='flow' } + local commands = Gui.scroll_table(container,275,2) + commands.style = 'bordered_table' + + -- Add the rules to the table + for name,command in pairs(Commands.get(player)) do + description_label(commands,100,name) + description_label(commands,440,command.help) + end + + return container +end)) --- Content area for the servers tab -- @element servers_content Tab({'readme.servers-tab'},{'readme.servers-tooltip'}, From 74675f2d19bff6618ec16f95a7693b0ded9f7419 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 25 Mar 2020 21:45:30 +0000 Subject: [PATCH 53/81] Added servers tab --- config/chat_reply.lua | 2 ++ config/compilatron.lua | 1 + locale/en/addons.cfg | 2 ++ locale/en/gui.cfg | 3 +++ modules/gui/readme.lua | 29 +++++++++++++++++++++++++---- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/config/chat_reply.lua b/config/chat_reply.lua index 8b8343c5..f1ae92a7 100644 --- a/config/chat_reply.lua +++ b/config/chat_reply.lua @@ -17,6 +17,8 @@ return { ['wiki']={'info.wiki'}, ['status']={'info.status'}, ['github']={'info.github'}, + ['patreon']={'info.patreon'}, + ['donate']={'info.patreon'}, ['command']={'info.custom-commands'}, ['commands']={'info.custom-commands'}, ['softmod']={'info.softmod'}, diff --git a/config/compilatron.lua b/config/compilatron.lua index 6b69601d..00c9ddcf 100644 --- a/config/compilatron.lua +++ b/config/compilatron.lua @@ -19,6 +19,7 @@ return { {'info.status'}, {'info.lhd'}, {'info.github'}, + {'info.patreon'}, } } } \ No newline at end of file diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index e526e53f..86081d87 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -13,6 +13,7 @@ wiki=https://wiki.explosivegaming.nl/ feedback=https://exp.fider.io/ status=https://status.explosivegaming.nl github=https://github.com/explosivegaming/scenario +patreon=https://www.patreon.com/ExpGaming [info] players-online=There are __1__ players online @@ -23,6 +24,7 @@ wiki=You can get more information about us and the custom scenario from our wiki feedback=Do you have feedback? leave it at https://exp.fider.io/ status=Want to check if out servers are down? Visit: https://status.explosivegaming.nl github=Want to help improve our server with some extra features? Help us at: https://github.com/explosivegaming/scenario +patreon=Consider supporting our server at: https://www.patreon.com/ExpGaming custom-commands=We use custom commands, such as /tag and /me, use /chelp for more info. read-readme=Make sure you have read the Readme (It can be found through the question mark on the top left) softmod=We run a softmod on our servers. A softmod is a custom scenario that runs on this server, an example is the player list. diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index f7217991..4c832f92 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -128,5 +128,8 @@ commands-tooltip=Commands which you are able to use commands-general=We have lots of custom commands which you are able to use. Below you can find a list of all the commands that you are allowed to use and what they do. If you need more information or want to search for a command you can use our /search-help command. servers-tab=Servers servers-tooltip=Links to our other servers and sites +servers-general=This is only one of our servers for factorio, we host alot of others as well. Below you can find details about all the servers that we host as well as links to our external services such as discord or github. +servers-factorio=ExpGaming - S1 Public: This is our 48 hour reset experimental server.\nExpGaming - S2 Public: This is our 48 hour reset stable server.\nExpGaming - S3 Weekly: This is our weekly reset experimental server.\nExpGaming - S4 Weekly: This is our weekly reset stable server.\nExpGaming - S5 Modded: This is our modded server, see discord for details.\nExpGaming - S6 Donator: This is our donator only server, online when requested.\nExpGaming - S7 Event: This is our event server, we try to run an event every weekend\nExpGaming - S8 T̷-̶s̶-̴:̷ ̵N̵o̴ ̶o̷-̶e̵ ̴k̸n̷-̶w̵s̸ ̴w̷h̷a̶-̶ ̷h̴a̴p̷p̴e̷n̷s̸ ̷o̶n̴ ̷t̶h̴-̶s̶ ̷s̷e̶r̸v̸e̴r̷,̶ ̸i̸t̴ ̷m̶-̸g̴h̶t̷ ̸n̸-̶t̵ ̷e̴v̸e̸n̶t̷ ̵-̷x̴i̵s̶t̸.̸ +servers-external=__1__\n__2__ backers-tab=Backers backers-tooltip=People who have helped make our server \ No newline at end of file diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index b969b113..6e70cc1e 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -151,13 +151,34 @@ Gui.element(function(_,parent) return container end)) + --- Content area for the servers tab -- @element servers_content Tab({'readme.servers-tab'},{'readme.servers-tooltip'}, -Gui.element{ - type = 'label', - caption = 'Servers' -}) +Gui.element(function(_,parent) + local container = parent.add{ type='flow', direction='vertical' } + + -- Add the title to the content + title(container,260,{'readme.servers-tab'}) + + -- Add the tab description + description_label(container,575,{'readme.servers-general'}) + Gui.bar(container) + + -- Create the external links string + local result + local keys = {'discord','website','patreon','status','github'} + for i,key in ipairs(keys) do + if i == 1 then result = {'info.'..key} + else result = {'readme.servers-external',result,{'info.'..key}} end + end + + -- Add the other information to the gui + description_label(sub_content(container),575,{'readme.servers-factorio'}) + description_label(sub_content(container),575,result) + + return container +end)) --- Content area for the servers tab -- @element backers_content From 29d879c17941dc4d4f37eec6f88d6ad246f83d59 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 25 Mar 2020 22:59:15 +0000 Subject: [PATCH 54/81] Added backer tab --- locale/en/gui.cfg | 8 ++- modules/gui/readme.lua | 120 +++++++++++++++++++++++++++++++++++------ 2 files changed, 112 insertions(+), 16 deletions(-) diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 4c832f92..75e7a4e2 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -132,4 +132,10 @@ servers-general=This is only one of our servers for factorio, we host alot of ot servers-factorio=ExpGaming - S1 Public: This is our 48 hour reset experimental server.\nExpGaming - S2 Public: This is our 48 hour reset stable server.\nExpGaming - S3 Weekly: This is our weekly reset experimental server.\nExpGaming - S4 Weekly: This is our weekly reset stable server.\nExpGaming - S5 Modded: This is our modded server, see discord for details.\nExpGaming - S6 Donator: This is our donator only server, online when requested.\nExpGaming - S7 Event: This is our event server, we try to run an event every weekend\nExpGaming - S8 T̷-̶s̶-̴:̷ ̵N̵o̴ ̶o̷-̶e̵ ̴k̸n̷-̶w̵s̸ ̴w̷h̷a̶-̶ ̷h̴a̴p̷p̴e̷n̷s̸ ̷o̶n̴ ̷t̶h̴-̶s̶ ̷s̷e̶r̸v̸e̴r̷,̶ ̸i̸t̴ ̷m̶-̸g̴h̶t̷ ̸n̸-̶t̵ ̷e̴v̸e̸n̶t̷ ̵-̷x̴i̵s̶t̸.̸ servers-external=__1__\n__2__ backers-tab=Backers -backers-tooltip=People who have helped make our server \ No newline at end of file +backers-tooltip=People who have helped make our server +backers-general=We would like to thank all our staff and backers who have helped our comunity grow. Our staff have helped to keep our servers safe from trolls and fun places to play. Our backers have helped us to cover our running costs and provide a great comunity for us all to enjoy together. +backers-management=Administrators +backers-board=Board Members and Senior Backers +backers-staff=Staff Members +backers-backers=Sponsors and Supporters +backers-active=Active Players \ No newline at end of file diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index 6e70cc1e..8bdbb159 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -15,6 +15,8 @@ local function Tab(caption,tooltip,element_define) tabs[#tabs+1] = {caption,tooltip,element_define} end +local frame_width = 595 + local function description_label(parent,width,caption) local label = parent.add{ type = 'label', @@ -91,9 +93,9 @@ Gui.element(function(_,parent) end -- Add the other information to the gui - description_label(sub_content(container),575,{'readme.welcome-general',server_details.reset_time}) - description_label(sub_content(container),575,{'readme.welcome-roles',table.concat(role_names,', ')}) - description_label(sub_content(container),575,{'readme.welcome-chat'}) + description_label(sub_content(container),frame_width,{'readme.welcome-general',server_details.reset_time}) + description_label(sub_content(container),frame_width,{'readme.welcome-roles',table.concat(role_names,', ')}) + description_label(sub_content(container),frame_width,{'readme.welcome-chat'}) return container end)) @@ -108,7 +110,7 @@ Gui.element(function(_,parent) title(container,267,{'readme.rules-tab'}) -- Add the tab description - description_label(container,575,{'readme.rules-general'}) + description_label(container,frame_width,{'readme.rules-general'}) Gui.bar(container) -- Add a table for the rules @@ -118,7 +120,7 @@ Gui.element(function(_,parent) -- Add the rules to the table for i = 1,15 do - description_label(rules,555,{'readme.rules-'..i}) + description_label(rules,560,{'readme.rules-'..i}) end return container @@ -135,10 +137,10 @@ Gui.element(function(_,parent) title(container,250,{'readme.commands-tab'}) -- Add the tab description - description_label(container,575,{'readme.commands-general'}) + description_label(container,frame_width,{'readme.commands-general'}) Gui.bar(container) - -- Add a table for the rules + -- Add a table for the commands container.add{ type='flow' } local commands = Gui.scroll_table(container,275,2) commands.style = 'bordered_table' @@ -146,7 +148,7 @@ Gui.element(function(_,parent) -- Add the rules to the table for name,command in pairs(Commands.get(player)) do description_label(commands,100,name) - description_label(commands,440,command.help) + description_label(commands,444,command.help) end return container @@ -162,7 +164,7 @@ Gui.element(function(_,parent) title(container,260,{'readme.servers-tab'}) -- Add the tab description - description_label(container,575,{'readme.servers-general'}) + description_label(container,frame_width,{'readme.servers-general'}) Gui.bar(container) -- Create the external links string @@ -174,19 +176,107 @@ Gui.element(function(_,parent) end -- Add the other information to the gui - description_label(sub_content(container),575,{'readme.servers-factorio'}) - description_label(sub_content(container),575,result) + description_label(sub_content(container),frame_width,{'readme.servers-factorio'}) + description_label(sub_content(container),frame_width,result) return container end)) +--- Contains the names for backer players +-- @element backer_table +local backer_table = +Gui.element(function(_,parent) + return parent.add{ + type = 'table', + column_count = 4, + style = 'bordered_table' + } +end) +:style{ + padding = 0, + cell_padding = 0, + vertical_align = 'center', + horizontally_stretchable = true +} + --- Content area for the servers tab -- @element backers_content Tab({'readme.backers-tab'},{'readme.backers-tooltip'}, -Gui.element{ - type = 'label', - caption = 'Backers' -}) +Gui.element(function(_,parent) + local container = parent.add{ type='flow', direction='vertical' } + + -- Add the title to the content + title(container,260,{'readme.backers-tab'}) + + -- Add the tab description + description_label(container,frame_width,{'readme.backers-general'}) + Gui.bar(container) + + -- Find which players will go where + local done = {} + local groups = { + Administrator = { _title={'readme.backers-management'}, _width=230 }, + Sponsor = { _title={'readme.backers-board'}, _width=145 }, -- change role to board + Donator = { _title={'readme.backers-backers'}, _width=196 }, -- change to backer + Moderator = { _title={'readme.backers-staff'}, _width=235 }, + Active = { _title={'readme.backers-active'}, _width=235 }, + } + + -- Fill by player roles + for player_name, player_roles in pairs(Roles.config.players) do + for role_name, players in pairs(groups) do + if table.contains(player_roles, role_name) then + done[player_name] = true + table.insert(players,player_name) + break + end + end + end + + -- Fill by active times + local active_time = 3*3600*60 + for _, player in pairs(game.players) do + if not done[player.name] then + if player.online_time > active_time then + table.insert(groups.Active,player.name) + end + end + end + + -- Draw the scroll + container.add{ type='flow' } + local scroll_pane = + container.add{ + type = 'scroll-pane', + direction = 'vertical', + horizontal_scroll_policy = 'never', + vertical_scroll_policy = 'auto', + style = 'scroll_pane_under_subheader' + } + + -- Set the style of the scroll pane + local scroll_style = scroll_pane.style + scroll_style.padding = {1,3} + scroll_style.maximal_height = 275 + scroll_style.horizontally_stretchable = true + + -- Add the different tables + for _, players in pairs(groups) do + title(scroll_pane, players._width, players._title) + local table = backer_table(scroll_pane) + for _,player_name in ipairs(players) do + description_label(table,140,player_name) + end + + if #players < 4 then + for i = 1,4-#players do + description_label(table,140) + end + end + end + + return container +end)) --- Main readme container for the center flow -- @element readme From 279e99ba2bfbc1bb620a654f6c10203d9169503c Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 25 Mar 2020 23:30:34 +0000 Subject: [PATCH 55/81] Remade server tab --- locale/en/gui.cfg | 20 ++++++++- modules/gui/readme.lua | 96 ++++++++++++++++++++++++------------------ 2 files changed, 72 insertions(+), 44 deletions(-) diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 75e7a4e2..200fe0db 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -129,8 +129,24 @@ commands-general=We have lots of custom commands which you are able to use. Belo servers-tab=Servers servers-tooltip=Links to our other servers and sites servers-general=This is only one of our servers for factorio, we host alot of others as well. Below you can find details about all the servers that we host as well as links to our external services such as discord or github. -servers-factorio=ExpGaming - S1 Public: This is our 48 hour reset experimental server.\nExpGaming - S2 Public: This is our 48 hour reset stable server.\nExpGaming - S3 Weekly: This is our weekly reset experimental server.\nExpGaming - S4 Weekly: This is our weekly reset stable server.\nExpGaming - S5 Modded: This is our modded server, see discord for details.\nExpGaming - S6 Donator: This is our donator only server, online when requested.\nExpGaming - S7 Event: This is our event server, we try to run an event every weekend\nExpGaming - S8 T̷-̶s̶-̴:̷ ̵N̵o̴ ̶o̷-̶e̵ ̴k̸n̷-̶w̵s̸ ̴w̷h̷a̶-̶ ̷h̴a̴p̷p̴e̷n̷s̸ ̷o̶n̴ ̷t̶h̴-̶s̶ ̷s̷e̶r̸v̸e̴r̷,̶ ̸i̸t̴ ̷m̶-̸g̴h̶t̷ ̸n̸-̶t̵ ̷e̴v̸e̸n̶t̷ ̵-̷x̴i̵s̶t̸.̸ -servers-external=__1__\n__2__ +servers-factorio=Factorio Servers +servers-1=S1 Public +servers-d1=This is our 48 hour reset experimental server. +servers-2=S2 Public +servers-d2=This is our 48 hour reset stable server. +servers-3=S3 Weekly +servers-d3=This is our weekly reset experimental server. +servers-4=S4 Weekly +servers-d4=This is our weekly reset stable server. +servers-5=S5 Modded +servers-d5=This is our modded server, see discord for details. +servers-6=S6 Donator +servers-d6=This is our donator only server, online when requested. +servers-7=S7 Event +servers-d7=This is our event server, we try to run an event every weekend +servers-8=S8 T̷-̶s̶-̴:̷ +servers-d8=N̵o̴ ̶o̷-̶e̵ ̴k̸n̷-̶w̵s̸ ̴w̷h̷a̶-̶ ̷h̴a̴p̷p̴e̷n̷s̸ ̷o̶n̴ ̷t̶h̴-̶s̶ ̷s̷e̶r̸v̸e̴r̷,̶ ̸i̸t̴ ̷m̶-̸g̴h̶t̷ ̸n̸-̶t̵ ̷e̴v̸e̸n̶t̷ ̵-̷x̴i̵s̶t̸.̸ +servers-external=External Links backers-tab=Backers backers-tooltip=People who have helped make our server backers-general=We would like to thank all our staff and backers who have helped our comunity grow. Our staff have helped to keep our servers safe from trolls and fun places to play. Our backers have helped us to cover our running costs and provide a great comunity for us all to enjoy together. diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index 8bdbb159..6d609d9c 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -63,6 +63,41 @@ Gui.element(function(_,parent,bar_size,caption) return title_label end) +--- Table which has a title above it +-- @element title_table +local title_table = +Gui.element(function(_,parent,bar_size,caption,column_count) + title(parent, bar_size, caption) + + return parent.add{ + type = 'table', + column_count = column_count, + style = 'bordered_table' + } +end) +:style{ + padding = 0, + cell_padding = 0, + vertical_align = 'center', + horizontally_stretchable = true +} + +--- Scroll to be used with title tables +-- @element title_table_scroll +local title_table_scroll = +Gui.element{ + type = 'scroll-pane', + direction = 'vertical', + horizontal_scroll_policy = 'never', + vertical_scroll_policy = 'auto', + style = 'scroll_pane_under_subheader' +} +:style{ + padding = {1,3}, + maximal_height = 275, + horizontally_stretchable = true, +} + --- Content area for the welcome tab -- @element welcome_content Tab({'readme.welcome-tab'},{'readme.welcome-tooltip'}, @@ -84,6 +119,7 @@ Gui.element(function(_,parent) -- Add the description to the top flow description_label(top_vertical_flow,380,server_details.description) Gui.bar(container) + container.add{ type='flow' }.style.height = 4 -- Get the names of the roles the player has local player_roles = Roles.get_player_roles(player) @@ -167,38 +203,28 @@ Gui.element(function(_,parent) description_label(container,frame_width,{'readme.servers-general'}) Gui.bar(container) - -- Create the external links string - local result - local keys = {'discord','website','patreon','status','github'} - for i,key in ipairs(keys) do - if i == 1 then result = {'info.'..key} - else result = {'readme.servers-external',result,{'info.'..key}} end + -- Draw the scroll + container.add{ type='flow' } + local scroll_pane = title_table_scroll(container) + scroll_pane.style.maximal_height = 295 + + -- Add the dactorio servers + local factoiro_servers = title_table(scroll_pane, 225, {'readme.servers-factorio'}, 2) + for i = 1,8 do + description_label(factoiro_servers,106,{'readme.servers-'..i}) + description_label(factoiro_servers,462,{'readme.servers-d'..i}) end - -- Add the other information to the gui - description_label(sub_content(container),frame_width,{'readme.servers-factorio'}) - description_label(sub_content(container),frame_width,result) + -- Add the external links + local external_links = title_table(scroll_pane, 235, {'readme.servers-external'}, 2) + for _,key in ipairs{'discord','website','patreon','status','github'} do + description_label(external_links,106,key:gsub("^%l", string.upper)) + description_label(external_links,462,{'links.'..key}) + end return container end)) ---- Contains the names for backer players --- @element backer_table -local backer_table = -Gui.element(function(_,parent) - return parent.add{ - type = 'table', - column_count = 4, - style = 'bordered_table' - } -end) -:style{ - padding = 0, - cell_padding = 0, - vertical_align = 'center', - horizontally_stretchable = true -} - --- Content area for the servers tab -- @element backers_content Tab({'readme.backers-tab'},{'readme.backers-tooltip'}, @@ -245,25 +271,11 @@ Gui.element(function(_,parent) -- Draw the scroll container.add{ type='flow' } - local scroll_pane = - container.add{ - type = 'scroll-pane', - direction = 'vertical', - horizontal_scroll_policy = 'never', - vertical_scroll_policy = 'auto', - style = 'scroll_pane_under_subheader' - } - - -- Set the style of the scroll pane - local scroll_style = scroll_pane.style - scroll_style.padding = {1,3} - scroll_style.maximal_height = 275 - scroll_style.horizontally_stretchable = true + local scroll_pane = title_table_scroll(container) -- Add the different tables for _, players in pairs(groups) do - title(scroll_pane, players._width, players._title) - local table = backer_table(scroll_pane) + local table = title_table(scroll_pane, players._width, players._title, 4) for _,player_name in ipairs(players) do description_label(table,140,player_name) end From ce798d5d6e69a444629452dbc45c545de8151f2c Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 26 Mar 2020 00:35:40 +0000 Subject: [PATCH 56/81] Cleaned up file --- expcore/gui/defines.lua | 58 +++++++++++++++- locale/en/gui.cfg | 1 + modules/gui/readme.lua | 143 +++++++++++++++------------------------- 3 files changed, 110 insertions(+), 92 deletions(-) diff --git a/expcore/gui/defines.lua b/expcore/gui/defines.lua index 41af4c32..b61322e7 100644 --- a/expcore/gui/defines.lua +++ b/expcore/gui/defines.lua @@ -219,7 +219,7 @@ end) --[[-- Used to make a solid white bar in a gui @element Gui.bar -@tparam LuaGuiElement parent the parent element to which the container will be added +@tparam LuaGuiElement parent the parent element to which the bar will be added @tparam number width the width of the bar that will be made, if not given bar will strech to fill the parent @usage-- Adding a bar to a gui @@ -239,4 +239,60 @@ end) style.color = {r=255,g=255,b=255} if width then style.width = width else style.horizontally_stretchable = true end +end) + +--[[-- Used to make a label which is centered and of a certian size +@element Gui.centered_label +@tparam LuaGuiElement parent the parent element to which the label will be added +@tparam number width the width of the label, must be given in order to center the caption +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the label +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the label + +@usage-- Adding a centered label +local label = Gui.centered_label(parent, 100, 'This is centered') + +]] +Gui.centered_label = +Gui.element(function(_,parent,width,caption,tooltip) + local label = parent.add{ + type = 'label', + caption = caption, + tooltip = tooltip, + style = 'description_label' + } + + local style = label.style + style.horizontal_align = 'center' + style.single_line = false + style.width = width + + return label +end) + +--[[-- Used to make a title which has two bars on either side +@element Gui.title_label +@tparam LuaGuiElement parent the parent element to which the label will be added +@tparam number width the width of the first bar, this can be used to position the label +@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the label +@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the label + +@usage-- Adding a centered label +local label = Gui.centered_label(parent, 100, 'This is centered') + +]] +Gui.title_label = +Gui.element(function(_,parent,width,caption,tooltip) + local title_flow = parent.add{ type='flow' } + title_flow.style.vertical_align = 'center' + + Gui.bar(title_flow,width) + local title_label = title_flow.add{ + type = 'label', + caption = caption, + tooltip = tooltip, + style = 'heading_1_label' + } + Gui.bar(title_flow) + + return title_label end) \ No newline at end of file diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 200fe0db..9d340f95 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -147,6 +147,7 @@ servers-d7=This is our event server, we try to run an event every weekend servers-8=S8 T̷-̶s̶-̴:̷ servers-d8=N̵o̴ ̶o̷-̶e̵ ̴k̸n̷-̶w̵s̸ ̴w̷h̷a̶-̶ ̷h̴a̴p̷p̴e̷n̷s̸ ̷o̶n̴ ̷t̶h̴-̶s̶ ̷s̷e̶r̸v̸e̴r̷,̶ ̸i̸t̴ ̷m̶-̸g̴h̶t̷ ̸n̸-̶t̵ ̷e̴v̸e̸n̶t̷ ̵-̷x̴i̵s̶t̸.̸ servers-external=External Links +servers-open-in-browser=Open in your browser backers-tab=Backers backers-tooltip=People who have helped make our server backers-general=We would like to thank all our staff and backers who have helped our comunity grow. Our staff have helped to keep our servers safe from trolls and fun places to play. Our backers have helped us to cover our running costs and provide a great comunity for us all to enjoy together. diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index 6d609d9c..9d822819 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -12,23 +12,12 @@ local Game = require 'utils.game' --- @dep utils.game local tabs = {} local function Tab(caption,tooltip,element_define) - tabs[#tabs+1] = {caption,tooltip,element_define} + tabs[#tabs+1] = {caption, tooltip, element_define} end -local frame_width = 595 - -local function description_label(parent,width,caption) - local label = parent.add{ - type = 'label', - caption = caption, - style = 'description_label' - } - - local style = label.style - style.horizontal_align = 'center' - style.single_line = false - style.width = width -end +local frame_width = 595 -- controls width of top descritions +local title_width = 270 -- controls the centering of the titles +local scroll_hieght = 275 -- controls the height of the scrolls --- Sub content area used within the content areas -- @element sub_content @@ -45,29 +34,11 @@ end) horizontal_align = 'center' } ---- Title element with bars on each side --- @element title -local title = -Gui.element(function(_,parent,bar_size,caption) - local title_flow = parent.add{ type='flow' } - title_flow.style.vertical_align = 'center' - - Gui.bar(title_flow,bar_size) - local title_label = title_flow.add{ - type = 'label', - caption = caption, - style = 'heading_1_label' - } - Gui.bar(title_flow) - - return title_label -end) - ---- Table which has a title above it +--- Table which has a title above it above it -- @element title_table local title_table = Gui.element(function(_,parent,bar_size,caption,column_count) - title(parent, bar_size, caption) + Gui.title_label(parent, bar_size, caption) return parent.add{ type = 'table', @@ -82,7 +53,7 @@ end) horizontally_stretchable = true } ---- Scroll to be used with title tables +--- Scroll to be used with Gui.title_label tables -- @element title_table_scroll local title_table_scroll = Gui.element{ @@ -94,7 +65,7 @@ Gui.element{ } :style{ padding = {1,3}, - maximal_height = 275, + maximal_height = scroll_hieght, horizontally_stretchable = true, } @@ -108,18 +79,15 @@ Gui.element(function(_,parent) -- Set up the top flow with logos local top_flow = container.add{ type='flow' } - top_flow.add{ type='sprite', sprite='file/modules/gui/logo.png'} + top_flow.add{ type='sprite', sprite='file/modules/gui/logo.png' } local top_vertical_flow = top_flow.add{ type='flow', direction='vertical' } - top_flow.add{ type='sprite', sprite='file/modules/gui/logo.png'} + top_flow.add{ type='sprite', sprite='file/modules/gui/logo.png' } top_vertical_flow.style.horizontal_align = 'center' - -- Add the title to the top flow - title(top_vertical_flow,62,'Welcome to '..server_details.name) - - -- Add the description to the top flow - description_label(top_vertical_flow,380,server_details.description) + -- Add the title and description to the top flow + Gui.title_label(top_vertical_flow, 62, 'Welcome to '..server_details.name) + Gui.centered_label(top_vertical_flow, 380, server_details.description) Gui.bar(container) - container.add{ type='flow' }.style.height = 4 -- Get the names of the roles the player has local player_roles = Roles.get_player_roles(player) @@ -129,9 +97,10 @@ Gui.element(function(_,parent) end -- Add the other information to the gui - description_label(sub_content(container),frame_width,{'readme.welcome-general',server_details.reset_time}) - description_label(sub_content(container),frame_width,{'readme.welcome-roles',table.concat(role_names,', ')}) - description_label(sub_content(container),frame_width,{'readme.welcome-chat'}) + container.add{ type='flow' }.style.height = 4 + Gui.centered_label(sub_content(container), frame_width, {'readme.welcome-general', server_details.reset_time}) + Gui.centered_label(sub_content(container), frame_width, {'readme.welcome-roles', table.concat(role_names,', ')}) + Gui.centered_label(sub_content(container), frame_width, {'readme.welcome-chat'}) return container end)) @@ -142,21 +111,20 @@ Tab({'readme.rules-tab'},{'readme.rules-tooltip'}, Gui.element(function(_,parent) local container = parent.add{ type='flow', direction='vertical' } - -- Add the title to the content - title(container,267,{'readme.rules-tab'}) - - -- Add the tab description - description_label(container,frame_width,{'readme.rules-general'}) + -- Add the title and description to the content + Gui.title_label(container, title_width-3, {'readme.rules-tab'}) + Gui.centered_label(container, frame_width, {'readme.rules-general'}) Gui.bar(container) + container.add{ type='flow' } -- Add a table for the rules - container.add{ type='flow' } - local rules = Gui.scroll_table(container,275,1) + local rules = Gui.scroll_table(container, scroll_hieght, 1) rules.style = 'bordered_table' + rules.style.cell_padding = 4 -- Add the rules to the table for i = 1,15 do - description_label(rules,560,{'readme.rules-'..i}) + Gui.centered_label(rules, 565, {'readme.rules-'..i}) end return container @@ -169,22 +137,21 @@ Gui.element(function(_,parent) local container = parent.add{ type='flow', direction='vertical' } local player = Gui.get_player_from_element(parent) - -- Add the title to the content - title(container,250,{'readme.commands-tab'}) - - -- Add the tab description - description_label(container,frame_width,{'readme.commands-general'}) + -- Add the title and description to the content + Gui.title_label(container, title_width-20, {'readme.commands-tab'}) + Gui.centered_label(container, frame_width, {'readme.commands-general'}) Gui.bar(container) + container.add{ type='flow' } -- Add a table for the commands - container.add{ type='flow' } - local commands = Gui.scroll_table(container,275,2) + local commands = Gui.scroll_table(container, scroll_hieght, 2) commands.style = 'bordered_table' + commands.style.cell_padding = 0 -- Add the rules to the table for name,command in pairs(Commands.get(player)) do - description_label(commands,100,name) - description_label(commands,444,command.help) + Gui.centered_label(commands, 120, name) + Gui.centered_label(commands, 450, command.help) end return container @@ -196,30 +163,28 @@ Tab({'readme.servers-tab'},{'readme.servers-tooltip'}, Gui.element(function(_,parent) local container = parent.add{ type='flow', direction='vertical' } - -- Add the title to the content - title(container,260,{'readme.servers-tab'}) - - -- Add the tab description - description_label(container,frame_width,{'readme.servers-general'}) + -- Add the title and description to the content + Gui.title_label(container, title_width-10, {'readme.servers-tab'}) + Gui.centered_label(container, frame_width, {'readme.servers-general'}) Gui.bar(container) + container.add{ type='flow' } -- Draw the scroll - container.add{ type='flow' } local scroll_pane = title_table_scroll(container) - scroll_pane.style.maximal_height = 295 + scroll_pane.style.maximal_height = scroll_hieght + 20 -- the text is a bit shorter - -- Add the dactorio servers + -- Add the factorio servers local factoiro_servers = title_table(scroll_pane, 225, {'readme.servers-factorio'}, 2) for i = 1,8 do - description_label(factoiro_servers,106,{'readme.servers-'..i}) - description_label(factoiro_servers,462,{'readme.servers-d'..i}) + Gui.centered_label(factoiro_servers, 110, {'readme.servers-'..i}) + Gui.centered_label(factoiro_servers, 460, {'readme.servers-d'..i}) end -- Add the external links local external_links = title_table(scroll_pane, 235, {'readme.servers-external'}, 2) for _,key in ipairs{'discord','website','patreon','status','github'} do - description_label(external_links,106,key:gsub("^%l", string.upper)) - description_label(external_links,462,{'links.'..key}) + Gui.centered_label(external_links, 110, key:gsub("^%l", string.upper)) + Gui.centered_label(external_links, 460, {'links.'..key}, {'readme.servers-open-in-browser'}) end return container @@ -231,12 +196,11 @@ Tab({'readme.backers-tab'},{'readme.backers-tooltip'}, Gui.element(function(_,parent) local container = parent.add{ type='flow', direction='vertical' } - -- Add the title to the content - title(container,260,{'readme.backers-tab'}) - - -- Add the tab description - description_label(container,frame_width,{'readme.backers-general'}) + -- Add the title and description to the content + Gui.title_label(container, title_width-10, {'readme.backers-tab'}) + Gui.centered_label(container, frame_width, {'readme.backers-general'}) Gui.bar(container) + container.add{ type='flow' } -- Find which players will go where local done = {} @@ -269,20 +233,17 @@ Gui.element(function(_,parent) end end - -- Draw the scroll - container.add{ type='flow' } - local scroll_pane = title_table_scroll(container) - -- Add the different tables + local scroll_pane = title_table_scroll(container) for _, players in pairs(groups) do local table = title_table(scroll_pane, players._width, players._title, 4) for _,player_name in ipairs(players) do - description_label(table,140,player_name) + Gui.centered_label(table, 140, player_name) end if #players < 4 then for i = 1,4-#players do - description_label(table,140) + Gui.centered_label(table, 140) end end end @@ -302,11 +263,11 @@ Gui.element(function(event_trigger,parent) } -- Add the left hand side of the frame back, removed because of frame_tabbed_pane style - local left_lignment = Gui.alignment(container,nil,nil,'bottom') - left_lignment.style.padding = {32,0,0,0} + local left_alignment = Gui.alignment(container, nil, nil, 'bottom') + left_alignment.style.padding = {32,0,0,0} local left_side = - left_lignment.add{ + left_alignment.add{ type = 'frame', style = 'frame_without_right_side' } From 0d1d21ae09d14d1593a08f585c1b916f487afe4e Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 26 Mar 2020 12:55:39 +0000 Subject: [PATCH 57/81] Changed event server message --- locale/en/gui.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 9d340f95..15e4c113 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -143,7 +143,7 @@ servers-d5=This is our modded server, see discord for details. servers-6=S6 Donator servers-d6=This is our donator only server, online when requested. servers-7=S7 Event -servers-d7=This is our event server, we try to run an event every weekend +servers-d7=This is our event server, we try to run events at least once per week. servers-8=S8 T̷-̶s̶-̴:̷ servers-d8=N̵o̴ ̶o̷-̶e̵ ̴k̸n̷-̶w̵s̸ ̴w̷h̷a̶-̶ ̷h̴a̴p̷p̴e̷n̷s̸ ̷o̶n̴ ̷t̶h̴-̶s̶ ̷s̷e̶r̸v̸e̴r̷,̶ ̸i̸t̴ ̷m̶-̸g̴h̶t̷ ̸n̸-̶t̵ ̷e̴v̸e̸n̶t̷ ̵-̷x̴i̵s̶t̸.̸ servers-external=External Links From 701ad7cb678cf382430ac6063adb874d74b31ed3 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 27 Mar 2020 17:51:08 +0000 Subject: [PATCH 58/81] Added server ups --- config/_file_loader.lua | 1 + config/roles.lua | 1 + modules/gui/server-ups.lua | 62 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 modules/gui/server-ups.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 35a07946..73be7622 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -48,6 +48,7 @@ return { 'modules.gui.warp-list', 'modules.gui.task-list', 'modules.gui.player-list', + 'modules.gui.server-ups', 'modules.commands.debug', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins diff --git a/config/roles.lua b/config/roles.lua index ff40131f..22fba6e9 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -216,6 +216,7 @@ local default = Roles.new_role('Guest','') 'command/find-on-map', 'command/report', 'command/ratio', + 'command/server-ups', 'gui/player-list', 'gui/rocket-info', 'gui/science-info', diff --git a/modules/gui/server-ups.lua b/modules/gui/server-ups.lua new file mode 100644 index 00000000..021dee03 --- /dev/null +++ b/modules/gui/server-ups.lua @@ -0,0 +1,62 @@ +--[[-- Gui Module - Server UPS + - Adds a server ups counter in the top right and a command to toggle is + @gui sverer-ups + @alias sverer_ups +]] + +local Gui = require 'expcore.gui' --- @dep expcore.gui +local Event = require 'utils.event' --- @dep utils.event +local Commands = require 'expcore.commands' --- @dep expcore.commands + +--- Label to show the server ups +-- @element sverer_ups +local sverer_ups = +Gui.element{ + type = 'label', + caption = 'Server UPS = 60.0' +} +:style{ + font = 'default-game' +} + +--- Toggles if the server ups is visbile +-- @command server-ups +Commands.new_command('server-ups','Toggle the server ups display') +:add_alias('sups','ups') +:register(function(player) + local label = player.gui.screen[sverer_ups.name] + label.visible = not label.visible +end) + +-- Set the location of the label +-- 1920x1080: x=1455, y=30 (ui scale 100%) +local function set_location(event) + local player = game.players[event.player_index] + local label = player.gui.screen[sverer_ups.name] + local res = player.display_resolution + local uis = player.display_scale + label.location = { x=res.width-465*uis, y=30*uis } +end + +-- Draw the label when the player joins +Event.add(defines.events.on_player_created,function(event) + local player = game.players[event.player_index] + local label = sverer_ups(player.gui.screen) + label.visible = false + set_location(event) +end) + +-- Update the caption for all online players +Event.on_nth_tick(60,function() + local caption = 'Server UPS = 60.0' + if global.ext and global.ext.server_ups then + caption = 'Server UPS = '..global.ext.server_ups + end + for _,player in pairs(game.connected_players) do + player.gui.screen[sverer_ups.name].caption = caption + end +end) + +-- Update when res or ui scale changes +Event.add(defines.events.on_player_display_resolution_changed,set_location) +Event.add(defines.events.on_player_display_scale_changed,set_location) \ No newline at end of file From e8f86ac054a31928284c61c302bd15113e39adf6 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 27 Mar 2020 17:54:46 +0000 Subject: [PATCH 59/81] Made check for ext --- locale/en/commands.cfg | 2 ++ modules/gui/server-ups.lua | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/locale/en/commands.cfg b/locale/en/commands.cfg index ab475d4b..4f25d450 100644 --- a/locale/en/commands.cfg +++ b/locale/en/commands.cfg @@ -74,3 +74,5 @@ home-set=Your home point has been set to x: __1__ y: __2__ return-set=Your return point has been set to x: __1__ y: __2__ home-get=Your home point is at x: __1__ y: __2__ +[expcom-server-ups] +no-ext=No external source was found, cannot display server ups. \ No newline at end of file diff --git a/modules/gui/server-ups.lua b/modules/gui/server-ups.lua index 021dee03..5c48b019 100644 --- a/modules/gui/server-ups.lua +++ b/modules/gui/server-ups.lua @@ -25,6 +25,9 @@ Commands.new_command('server-ups','Toggle the server ups display') :add_alias('sups','ups') :register(function(player) local label = player.gui.screen[sverer_ups.name] + if not global.ext or not global.ext.server_ups then + return Commands.error{'expcom-server-ups.no-ext'} + end label.visible = not label.visible end) @@ -48,12 +51,11 @@ end) -- Update the caption for all online players Event.on_nth_tick(60,function() - local caption = 'Server UPS = 60.0' if global.ext and global.ext.server_ups then - caption = 'Server UPS = '..global.ext.server_ups - end - for _,player in pairs(game.connected_players) do - player.gui.screen[sverer_ups.name].caption = caption + local caption = 'Server UPS = '..global.ext.server_ups + for _,player in pairs(game.connected_players) do + player.gui.screen[sverer_ups.name].caption = caption + end end end) From 7c1943d0c9550bc8659c9b2edb688e28beb46c42 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 28 Mar 2020 02:46:13 +0000 Subject: [PATCH 60/81] Fixed server mis-spell --- modules/gui/server-ups.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/gui/server-ups.lua b/modules/gui/server-ups.lua index 5c48b019..cba75d89 100644 --- a/modules/gui/server-ups.lua +++ b/modules/gui/server-ups.lua @@ -1,7 +1,7 @@ --[[-- Gui Module - Server UPS - Adds a server ups counter in the top right and a command to toggle is - @gui sverer-ups - @alias sverer_ups + @gui server-ups + @alias server_ups ]] local Gui = require 'expcore.gui' --- @dep expcore.gui @@ -9,8 +9,8 @@ local Event = require 'utils.event' --- @dep utils.event local Commands = require 'expcore.commands' --- @dep expcore.commands --- Label to show the server ups --- @element sverer_ups -local sverer_ups = +-- @element server_ups +local server_ups = Gui.element{ type = 'label', caption = 'Server UPS = 60.0' @@ -24,7 +24,7 @@ Gui.element{ Commands.new_command('server-ups','Toggle the server ups display') :add_alias('sups','ups') :register(function(player) - local label = player.gui.screen[sverer_ups.name] + local label = player.gui.screen[server_ups.name] if not global.ext or not global.ext.server_ups then return Commands.error{'expcom-server-ups.no-ext'} end @@ -35,7 +35,7 @@ end) -- 1920x1080: x=1455, y=30 (ui scale 100%) local function set_location(event) local player = game.players[event.player_index] - local label = player.gui.screen[sverer_ups.name] + local label = player.gui.screen[server_ups.name] local res = player.display_resolution local uis = player.display_scale label.location = { x=res.width-465*uis, y=30*uis } @@ -44,7 +44,7 @@ end -- Draw the label when the player joins Event.add(defines.events.on_player_created,function(event) local player = game.players[event.player_index] - local label = sverer_ups(player.gui.screen) + local label = server_ups(player.gui.screen) label.visible = false set_location(event) end) @@ -54,7 +54,7 @@ Event.on_nth_tick(60,function() if global.ext and global.ext.server_ups then local caption = 'Server UPS = '..global.ext.server_ups for _,player in pairs(game.connected_players) do - player.gui.screen[sverer_ups.name].caption = caption + player.gui.screen[server_ups.name].caption = caption end end end) From efcd86ff674e4d924e5f5958766de1eb3b68fda2 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 29 Mar 2020 17:36:55 +0100 Subject: [PATCH 61/81] Fixed factorio mis-spell --- modules/gui/readme.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index 9d822819..0992b52d 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -174,10 +174,10 @@ Gui.element(function(_,parent) scroll_pane.style.maximal_height = scroll_hieght + 20 -- the text is a bit shorter -- Add the factorio servers - local factoiro_servers = title_table(scroll_pane, 225, {'readme.servers-factorio'}, 2) + local factorio_servers = title_table(scroll_pane, 225, {'readme.servers-factorio'}, 2) for i = 1,8 do - Gui.centered_label(factoiro_servers, 110, {'readme.servers-'..i}) - Gui.centered_label(factoiro_servers, 460, {'readme.servers-d'..i}) + Gui.centered_label(factorio_servers, 110, {'readme.servers-'..i}) + Gui.centered_label(factorio_servers, 460, {'readme.servers-d'..i}) end -- Add the external links From 3141b8a75f029bc723d8998c281bfaeb74986db4 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 29 Mar 2020 18:43:55 +0100 Subject: [PATCH 62/81] Updated to new roles --- config/roles.lua | 111 +++++++++++++++++++++++------------------ expcore/roles.lua | 41 +++++++++++---- modules/gui/readme.lua | 24 +++++---- 3 files changed, 106 insertions(+), 70 deletions(-) diff --git a/config/roles.lua b/config/roles.lua index e621747d..943e3709 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -100,7 +100,7 @@ Roles.new_role('Trainee','TrMod') :set_flag('is_admin') :set_flag('is_spectator') :set_flag('report-immune') -:set_parent('Donator') +:set_parent('Veteran') :allow{ 'command/admin-chat', 'command/teleport', @@ -110,28 +110,42 @@ Roles.new_role('Trainee','TrMod') 'command/give-warning', 'command/get-warnings', 'command/get-reports', + 'command/jail', + 'command/unjail', 'command/kick', 'command/ban', } --- Trusted Roles -Roles.new_role('Sponsor','Spon') +Roles.new_role('Board Member','Board') :set_permission_group('Trusted') :set_custom_color{r=247,g=246,b=54} :set_flag('is_spectator') :set_flag('report-immune') :set_flag('instance-respawn') -:set_parent('Pay to Win') +:set_parent('Sponsor') :allow{ + 'command/goto', + 'command/repair', } -Roles.new_role('Pay to Win','P2W') +Roles.new_role('Senior Backer','Backer') :set_permission_group('Trusted') :set_custom_color{r=238,g=172,b=44} :set_flag('is_spectator') :set_flag('report-immune') :set_flag('instance-respawn') -:set_parent('Donator') +:set_parent('Sponsor') +:allow{ +} + +Roles.new_role('Sponsor','Spon') +:set_permission_group('Trusted') +:set_custom_color{r=238,g=172,b=44} +:set_flag('is_spectator') +:set_flag('report-immune') +:set_flag('instance-respawn') +:set_parent('Supporter') :allow{ 'gui/rocket-info/toggle-active', 'gui/rocket-info/remote_launch', @@ -143,7 +157,7 @@ Roles.new_role('Pay to Win','P2W') 'fast-tree-decon', } -Roles.new_role('Donator','Don') +Roles.new_role('Supporter','Sup') :set_permission_group('Trusted') :set_custom_color{r=230,g=99,b=34} :set_flag('is_spectator') @@ -242,9 +256,10 @@ Roles.define_role_order{ 'Administrator', 'Moderator', 'Trainee', + 'Board Member', + 'Senior Backer', 'Sponsor', - 'Pay to Win', - 'Donator', + 'Supporter', 'Partner', 'Veteran', 'Member', @@ -254,44 +269,44 @@ Roles.define_role_order{ } Roles.override_player_roles{ - Cooldude2606={'Senior Administrator','Administrator','Moderator','Member'}, - arty714={'Senior Administrator','Administrator','Moderator','Member'}, - mark9064={'Administrator','Moderator','Member'}, - Drahc_pro={'Administrator','Moderator','Member'}, - aldldl={'Sponsor','Administrator','Moderator','Member'}, - LoicB={'Sponsor','Trainee','Member'}, - ookl={'Sponsor','Moderator','Member'}, - cydes={'Pay to Win','Moderator','Member'}, - darklich14={'Pay to Win','Moderator','Member'}, - porelos={'Pay to Win','Moderator','Member'}, - SilentLog={'Pay to Win','Moderator','Member'}, - UUBlueFire={'Pay to Win','Moderator','Member'}, - XenoCyber={'Pay to Win','Moderator','Member'}, - Chromaddict={'Donator','Moderator','Member'}, - eissturm={'Donator','Moderator','Member'}, - freek18={'Donator','Moderator','Member'}, - M74132={'Donator','Moderator','Member'}, - thadius856={'Donator','Moderator','Member'}, - ['7h3w1z4rd']={'Moderator','Member'}, - AssemblyStorm={'Moderator','Member'}, - bombershark={'Moderator','Member'}, - CmonMate497={'Moderator','Member'}, - facere={'Moderator','Member'}, - FlipHalfling90={'Moderator','Member'}, - Gizan={'Pay to Win','Moderator','Member'}, - Hobbitkicker={'Moderator','Member'}, - jessi_gaming={'Trainee','Member'}, - Koroto={'Moderator','Member'}, - mafisch3={'Moderator','Member'}, - maplesyrup01={'Moderator','Member'}, - NextIdea={'Moderator','Member'}, - Phoenix27833={'Moderator','Member'}, - Rezz={'Moderator','Member'}, - Ruuyji={'Moderator','Member'}, - samy115={'Moderator','Member'}, - scarbvis={'Moderator','Member'}, - Tcheko={'Moderator','Member'}, - WhomstThouAmMe={'Moderator','Member'}, - Windbomb={'Moderator','Member'}, - tovernaar123={'Member'}, + ["Cooldude2606"]={"Senior Administrator","Moderator","Senior Backer","Supporter"}, + ["arty714"]={"Senior Administrator","Senior Backer","Supporter"}, + ["Drahc_pro"]={"Administrator","Moderator","Veteran","Member"}, + ["mark9064"]={"Administrator","Moderator","Member"}, + ["aldldl"]={"Administrator","Moderator","Senior Backer","Sponsor","Supporter","Member"}, + + ["ookl"]={"Moderator","Senior Backer","Sponsor","Supporter","Partner","Member"}, + ["hamsterbryan"]={"Moderator","Senior Backer","Supporter","Member"}, + ["M74132"]={"Moderator","Senior Backer","Sponsor","Supporter","Member"}, + ["LoicB"]={"Moderator","Senior Backer","Supporter","Veteran","Member"}, + ["UUBlueFire"]={"Moderator","Senior Backer","Supporter","Member"}, + + ["thadius856"]={"Moderator","Supporter","Member"}, + ["XenoCyber"]={"Moderator","Supporter","Partner","Member"}, + ["cydes"]={"Moderator","Supporter","Member"}, + ["darklich14"]={"Moderator","Supporter","Member"}, + ["SilentLog"]={"Moderator","Supporter","Member"}, + ["freek18"]={"Moderator","Supporter","Member"}, + ["porelos"]={"Moderator","Supporter","Member"}, + + ["7h3w1z4rd"]={"Moderator","Member"}, + ["Windbomb"]={"Moderator","Member"}, + ["Phoenix27833"]={"Moderator","Member"}, + ["banakeg"]={"Moderator","Member"}, + ["maplesyrup01"]={"Moderator","Member"}, + ["FlipHalfling90"]={"Moderator","Member"}, + ["Ruuyji"]={"Moderator","Member"}, + ["Gizan"]={"Moderator"}, + ["samy115"]={"Moderator","Member"}, + ["Hobbitkicker"]={"Moderator","Member"}, + ["facere"]={"Moderator","Member"}, + ["whoami32"]={"Moderator","Member"}, + ["NextIdea"]={"Moderator","Member"}, + ["mafisch3"]={"Moderator","Member"}, + ["Tcheko"]={"Moderator","Member"}, + ["AssemblyStorm"]={"Moderator","Veteran","Member"}, + ["connormkii"]={"Moderator","Veteran","Member"}, + ["Koroto"]={"Moderator","Veteran","Member"}, + ["scarbvis"]={"Moderator","Member"}, + ["CmonMate497"]={"Moderator","Member"} } diff --git a/expcore/roles.lua b/expcore/roles.lua index a9d68404..1163d84b 100644 --- a/expcore/roles.lua +++ b/expcore/roles.lua @@ -318,29 +318,34 @@ end -- @tparam LuaPlayer player the player that will be assigned the roles -- @tparam table roles table a of roles that the player will be given, can be one role and can be role names -- @tparam[opt=] string by_player_name the name of the player that will be shown in the log +-- @tparam[opt=false] boolean skip_checks when true there will be no checks are done for if the player is valid -- @tparam[opt=false] boolean silent when true there will be no game message printed -function Roles.assign_player(player,roles,by_player_name,silent) - player = Game.get_player_from_any(player) - if not player then return end +function Roles.assign_player(player,roles,by_player_name,skip_checks,silent) + local valid_player = Game.get_player_from_any(player) + if not skip_checks and not valid_player then return end if type(roles) ~= 'table' or roles.name then roles = {roles} end for _,role in pairs(roles) do role = Roles.get_role_from_any(role) if role then - role:add_player(player,false,true) + role:add_player(valid_player or player, valid_player == nil, true) end end - emit_player_roles_updated(player,'assign',roles,by_player_name,silent) + if valid_player then + emit_player_roles_updated(valid_player, 'assign', roles, by_player_name, silent) + end end --- Removes a player from the given role(s) with an option to pass a by player name used in the log -- @tparam LuaPlayer player the player that will have the roles removed -- @tparam table roles table a of roles to be removed from the player, can be one role and can be role names -- @tparam[opt=] string by_player_name the name of the player that will be shown in the logs +-- @tparam[opt=false] boolean skip_checks when true there will be no checks are done for if the player is valid -- @tparam[opt=false] boolean silent when true there will be no game message printed -function Roles.unassign_player(player,roles,by_player_name,silent) - player = Game.get_player_from_any(player) +function Roles.unassign_player(player,roles,by_player_name,skip_checks,silent) + local valid_player = Game.get_player_from_any(player) + if not skip_checks and not valid_player then return end if not player then return end if type(roles) ~= 'table' or roles.name then roles = {roles} @@ -348,10 +353,12 @@ function Roles.unassign_player(player,roles,by_player_name,silent) for _,role in pairs(roles) do role = Roles.get_role_from_any(role) if role then - role:remove_player(player,false,true) + role:remove_player(valid_player or player, valid_player == nil, true) end end - emit_player_roles_updated(player,'unassign',roles,by_player_name,silent) + if valid_player then + emit_player_roles_updated(valid_player, 'unassign', roles, by_player_name, silent) + end end --- Overrides all player roles with the given table of roles, useful to mass set roles on game start @@ -419,16 +426,28 @@ end function Roles.define_role_order(order) -- Clears and then rebuilds the order table Roles.config.order = {} + local done = {} for _,role in ipairs(order) do if type(role) == 'table' and role.name then + done[role.name] = true table.insert(Roles.config.order,role.name) else + done[role] = true table.insert(Roles.config.order,role) end end + -- Check no roles were missed + for role_name,_ in pairs(Role.config.roles) do + if not done[role_name] then + error('Role missing '..role_name..' from role order, all defined roles must be included.',2) + end + end -- Re-links roles to they parents as this is called at the end of the config - for index,role in pairs(Roles.config.order) do - role = Roles.config.roles[role] + for index,role_name in pairs(Roles.config.order) do + local role = Roles.config.roles[role_name] + if not role then + error('Role with name '..role_name..' has not beed defined, either define it or remove it from the order list.',2) + end role.index = index local parent = Roles.config.roles[role.parent] if parent then diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index 0992b52d..18c094af 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -205,20 +205,22 @@ Gui.element(function(_,parent) -- Find which players will go where local done = {} local groups = { - Administrator = { _title={'readme.backers-management'}, _width=230 }, - Sponsor = { _title={'readme.backers-board'}, _width=145 }, -- change role to board - Donator = { _title={'readme.backers-backers'}, _width=196 }, -- change to backer - Moderator = { _title={'readme.backers-staff'}, _width=235 }, - Active = { _title={'readme.backers-active'}, _width=235 }, + { _roles={'Senior Administrator','Administrator'}, _title={'readme.backers-management'}, _width=230 }, + { _roles={'Board Member','Senior Backer'}, _title={'readme.backers-board'}, _width=145 }, -- change role to board + { _roles={'Sponsor','Supporter'}, _title={'readme.backers-backers'}, _width=196 }, -- change to backer + { _roles={'Moderator','Trainee'}, _title={'readme.backers-staff'}, _width=235 }, + { _roles={}, _title={'readme.backers-active'}, _width=235 }, } -- Fill by player roles for player_name, player_roles in pairs(Roles.config.players) do - for role_name, players in pairs(groups) do - if table.contains(player_roles, role_name) then - done[player_name] = true - table.insert(players,player_name) - break + for _, players in ipairs(groups) do + for _, role_name in pairs(players._roles) do + if table.contains(player_roles, role_name) then + done[player_name] = true + table.insert(players,player_name) + break + end end end end @@ -235,7 +237,7 @@ Gui.element(function(_,parent) -- Add the different tables local scroll_pane = title_table_scroll(container) - for _, players in pairs(groups) do + for _, players in ipairs(groups) do local table = title_table(scroll_pane, players._width, players._title, 4) for _,player_name in ipairs(players) do Gui.centered_label(table, 140, player_name) From 6a2f99b06935cf2fa563dde02d16f80a08455bf0 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 29 Mar 2020 22:50:21 +0100 Subject: [PATCH 63/81] Removed useless files --- config/action_buttons.lua | 4 +- config/chat_reply.lua | 2 +- config/expcore-commands/parse_roles.lua | 2 +- control.lua | 27 +- expcore/commands.lua | 2 +- expcore/common.lua | 563 ++++++++---------- expcore/roles.lua | 6 +- modules/addons/death-logger.lua | 2 +- modules/addons/discord-alerts.lua | 4 +- modules/addons/greetings.lua | 2 +- modules/addons/random-player-colours.lua | 4 +- modules/addons/scorched-earth.lua | 2 +- modules/commands/admin-chat.lua | 2 +- modules/commands/clear-inventory.lua | 2 +- modules/commands/jail.lua | 2 +- modules/commands/rainbow.lua | 2 +- modules/commands/reports.lua | 2 +- modules/commands/roles.lua | 4 +- modules/commands/warnings.lua | 2 +- modules/control/jail.lua | 2 +- modules/control/production.lua | 4 +- modules/control/warps.lua | 3 +- modules/gui/debug/_g_view.lua | 2 +- modules/gui/debug/event_view.lua | 2 +- modules/gui/debug/expcore_gui_view.lua | 2 +- modules/gui/debug/expcore_store_view.lua | 2 +- modules/gui/debug/global_view.lua | 2 +- modules/gui/debug/main_view.lua | 2 +- modules/gui/debug/model.lua | 2 +- modules/gui/debug/package_view.lua | 6 +- modules/gui/debug/redmew_global_view.lua | 2 +- modules/gui/player-list.lua | 4 +- modules/gui/rocket-info.lua | 4 +- modules/gui/science-info.lua | 2 +- modules/gui/task-list.lua | 6 +- modules/gui/warp-list.lua | 6 +- {utils => overrides}/debug.lua | 2 +- {utils => overrides}/inspect.lua | 3 +- {utils => overrides}/math.lua | 2 +- .../print_override.lua => overrides/print.lua | 7 +- .../require.lua | 3 +- .../data_stages.lua => overrides/stages.lua | 2 + {utils => overrides}/table.lua | 210 ++++++- resources/version.lua | 2 - utils/alien_evolution_progress.lua | 179 ------ {resources => utils}/color_presets.lua | 0 utils/command.lua | 326 ---------- utils/core.lua | 223 ------- utils/dump_env.lua | 32 - utils/event.lua | 2 +- utils/game.lua | 2 +- utils/player_rewards.lua | 154 ----- utils/recipe_locker.lua | 58 -- utils/redmew_settings.lua | 178 ------ utils/state_machine.lua | 119 ---- utils/timestamp.lua | 152 ----- 56 files changed, 499 insertions(+), 1846 deletions(-) rename {utils => overrides}/debug.lua (99%) rename {utils => overrides}/inspect.lua (99%) rename {utils => overrides}/math.lua (99%) rename utils/print_override.lua => overrides/print.lua (69%) rename utils/require_override.lua => overrides/require.lua (75%) rename resources/data_stages.lua => overrides/stages.lua (91%) rename {utils => overrides}/table.lua (55%) delete mode 100644 resources/version.lua delete mode 100644 utils/alien_evolution_progress.lua rename {resources => utils}/color_presets.lua (100%) delete mode 100644 utils/command.lua delete mode 100644 utils/core.lua delete mode 100644 utils/dump_env.lua delete mode 100644 utils/player_rewards.lua delete mode 100644 utils/recipe_locker.lua delete mode 100644 utils/redmew_settings.lua delete mode 100644 utils/state_machine.lua delete mode 100644 utils/timestamp.lua diff --git a/config/action_buttons.lua b/config/action_buttons.lua index b5306cf1..77ad6b9d 100644 --- a/config/action_buttons.lua +++ b/config/action_buttons.lua @@ -12,8 +12,8 @@ local Game = require 'utils.game' --- @dep utils.game local Reports = require 'modules.control.reports' --- @dep modules.control.reports local Warnings = require 'modules.control.warnings' --- @dep modules.control.warnings local Jail = require 'modules.control.jail' --- @dep modules.control.jail -local Colors = require 'resources.color_presets' --- @dep resources.color_presets -local format_chat_player_name = ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common +local Colors = require 'utils.color_presets' --- @dep utils.color_presets +local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common local selected_player_store = '' local selected_action_store = '' diff --git a/config/chat_reply.lua b/config/chat_reply.lua index f1ae92a7..52eb80be 100644 --- a/config/chat_reply.lua +++ b/config/chat_reply.lua @@ -2,7 +2,7 @@ -- @config Chat-Reply local Async = require 'expcore.async' -local format_time = ext_require('expcore.common','format_time') --- @dep expcore.common +local format_time = _C.ext_require('expcore.common','format_time') --- @dep expcore.common local async_message = Async.register(function(player, message) player.print(message) diff --git a/config/expcore-commands/parse_roles.lua b/config/expcore-commands/parse_roles.lua index 20b0d51f..f6923404 100644 --- a/config/expcore-commands/parse_roles.lua +++ b/config/expcore-commands/parse_roles.lua @@ -9,7 +9,7 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Roles = require 'expcore.roles' --- @dep expcore.roles -local auto_complete = ext_require('expcore.common','auto_complete') --- @dep expcore.common +local auto_complete = _C.ext_require('expcore.common','auto_complete') --- @dep expcore.common require 'config.expcore-commands.parse_general' Commands.add_parse('role',function(input,player,reject) diff --git a/control.lua b/control.lua index 82237d76..5658ba42 100644 --- a/control.lua +++ b/control.lua @@ -5,24 +5,17 @@ -- this file is the landing point for all scenarios please DO NOT edit directly, further comments are to aid development log('[START] -----| Explosive Gaming Scenario Loader |-----') - --- Info on the data lifecycle and how we use it: https://github.com/Refactorio/RedMew/wiki/The-data-lifecycle log('[INFO] Setting up lua environment') -require 'resources.data_stages' -_LIFECYCLE = _STAGE.control -- Control stage --- Overrides the _G.print function -require 'utils.print_override' - --- Omitting the math library is a very bad idea -require 'utils.math' - --- Global Debug and make sure our version file is registered -Debug = require 'utils.debug' --- @dep utils.debug -require 'resources.version' - --- Global require function used to extract parts of a module, because simply being in common is not good enough -ext_require = require('expcore.common').ext_require --- @dep expcore.common.ext_require +-- Require the global overrides +require 'overrides.stages' -- Data stages used in factorio, often used to test for runtime +require 'overrides.print' -- Overrides the _G.print function +require 'overrides.math' -- Omitting the math library is a very bad idea +require 'overrides.table' -- Adds alot more functions to the table module +inspect = require 'overrides.inspect' -- Used to covert any value into human readable string +Debug = require 'overrides.debug' -- Global Debug module +_C = require('expcore.common') -- _C is used to store lots of common functions expected to be used +global.expgaming_version = '6.0.0' -- The current version for exp gaming scenario -- Please go to config/file_loader.lua to edit the files that are loaded log('[INFO] Getting file loader config') @@ -52,7 +45,7 @@ end -- Override the default require; require can no longer load new scripts log('[INFO] Require Overright! No more requires can be made!') -require 'utils.require_override' +require 'overrides.require' -- Logs all errors again to make it make it easy to find log('[INFO] All files loaded with '..#errors..' errors:') diff --git a/expcore/commands.lua b/expcore/commands.lua index a0b05475..a64370ef 100644 --- a/expcore/commands.lua +++ b/expcore/commands.lua @@ -196,7 +196,7 @@ ]] local Game = require 'utils.game' --- @dep utils.game -local player_return,write_json = ext_require('expcore.common','player_return','write_json') --- @dep expcore.common +local player_return,write_json = _C.ext_require('expcore.common','player_return','write_json') --- @dep expcore.common local Commands = { defines={ -- common values are stored error like signals diff --git a/expcore/common.lua b/expcore/common.lua index 1d9ebef0..be47f8dd 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -4,52 +4,276 @@ @alias Common ]] -local Colours = require 'resources.color_presets' --- @dep resources.color_presets +local Colours = require 'utils.color_presets' --- @dep utils.color_presets local Game = require 'utils.game' --- @dep utils.game local Util = require 'util' --- @dep util -require 'utils.table' -require 'utils.math' +require 'overrides.table' +require 'overrides.math' local Common = {} ---- Compare types faster for faster validation of params +--- Type Checking. +-- @section typeCheck + +--- Asserts the argument is of type test_type -- @usage type_check('foo','string') -- return true -- @usage type_check('foo') -- return false -- @tparam any value 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 Common.type_check(value,test_type) +function Common.type_check(value, test_type) return test_type and value and type(value) == test_type or not test_type and not value or false end --- Raises an error if the value is of the wrong type --- @usage type_check_error('foo','number','Value must be a number') -- will raise error "Value must be a number" +-- @usage type_error('foo','number','Value must be a number') -- will raise error "Value must be a number" -- @tparam any value the value that you want to test the type of -- @tparam string test_type the type that the value should be -- @tparam string error_message the error message that is returned -- @tparam number level the level to call the error on (level = 1 means the caller) -- @treturn boolean true if no error was called -function Common.type_check_error(value,test_type,error_message,level) +function Common.type_error(value, test_type, error_message, level) level = level and level+1 or 2 - return Common.test_type(value,test_type) or error(error_message,level) + return Common.type_check(value,test_type) or error(error_message,level) +end + +--- Asserts the argument is one of type test_types +-- @param value the variable to check +-- @param test_types the type as a table of strings +-- @treturn boolean true if value is one of test_types +function Common.multi_type_check(value, test_types) + local vtype = type(value) + for _, arg_type in ipairs(test_types) do + if vtype == arg_type then + return true + end + end + return false +end + +--- Raises an error if the value is of the wrong type +-- @usage multi_type_error('foo',{'string','table'},'Value must be a string or table') -- will raise error "Value must be a string or table" +-- @tparam any value the value that you want to test the type of +-- @tparam table test_types the type as a table of strings +-- @tparam string error_message the error message that is returned +-- @tparam number level the level to call the error on (level = 1 means the caller) +-- @treturn boolean true if no error was called +function Common.multi_type_error(value, test_types, error_message, level) + level = level and level+1 or 2 + return Common.mult_type_check(value, test_types) or error(error_message,level) end --- Raises an error when the value is the incorrect type, uses a consistent error message format --- @usage param_check('foo','number','repeat_count',2) -- will raise error "Invalid param #02 given to ; repeat_count is not of type number" +-- @usage validate_argument_type('foo','number','repeat_count',2) -- will raise error "Bad argument #02 to ""; "repeat_count" is of type string expected number" -- @tparam any value the value that you want to test the type of -- @tparam string test_type the type that the value should be -- @tparam string param_name the name of the param -- @tparam number param_number the number param it is -- @treturn boolean true if no error was raised -function Common.param_check(value,test_type,param_name,param_number) +function Common.validate_argument_type(value, test_type, param_name, param_number) if not Common.test_type(value,test_type) then local function_name = debug.getinfo(2,'n').name or '' - local error_message = string.format('Invalid param #%2d given to %s; %s is not of type %s',param_number,function_name,param_name,test_type) + local error_message = string.format('Bad argument #%2d to %q; %q is of type %s expected %s', param_number, function_name, param_name, type(value), test_type) return error(error_message,3) end return true end +--- Raises an error when the value is the incorrect type, uses a consistent error message format +-- @usage validate_argument_type('foo',{'string','table'},'repeat_count',2) -- will raise error "Bad argument #02 to ""; "repeat_count" is of type string expected string or table" +-- @tparam any value the value that you want to test the type of +-- @tparam string test_types the types that the value should be +-- @tparam string param_name the name of the param +-- @tparam number param_number the number param it is +-- @treturn boolean true if no error was raised +function Common.validate_argument_multi_type(value, test_types, param_name, param_number) + if not Common.multi_type_check(value,test_types) then + local function_name = debug.getinfo(2,'n').name or '' + local error_message = string.format('Bad argument #%2d to %q; %q is of type %s expected %s', param_number, function_name, param_name, type(value), table.concat(test_types,' or ')) + return error(error_message,3) + end + return true +end + +--- Value Returns. +-- @section valueReturns + +--- Tests if a string contains a given substring. +-- @tparam string s the string to check for the substring +-- @tparam string contains the substring to test for +-- @treturn boolean true if the substring was found in the string +function Common.string_contains(s, contains) + return s and string.find(s, contains) ~= nil +end + +--[[-- Used to resolve a value that could also be a function returning that value +@tparam any value the value which you want to test is not nil and if it is a function then call the function +@treturn any the value given or returned by value if it is a function +@usage-- Default value handling +-- if default value is not a function then it is returned +-- if it is a function then it is called with the first argument being self +local value = Common.resolve_value(self.defaut_value,self) +]] +function Common.resolve_value(value,...) + if value then + if type(value) == 'function' then + return value(...) + else + return value + end + end +end + +--- Returns a valid string with the name of the actor of a command. +-- @treturns string the name of the current actor +function Common.get_actor() + return game.player and game.player.name or '' +end + +--- Converts a varible into its boolean value, nil and false return false +-- @treturn boolean the boolean form of the varible +function Common.cast_bool(var) + return var and true or false +end + +--- Returns either the second or third argument based on the first argument +function Common.ternary(c, t, f) + return c and t or f +end + +--- Returns a string for a number with comma seperators +function Common.comma_value(n) -- credit http://richard.warburton.it + local left, num, right = string.match(n, '^([^%d]*%d)(%d*)(.-)$') + return left .. (num:reverse():gsub('(%d%d%d)', '%1,'):reverse()) .. right +end + +--- Sets a table element to value while also returning value. +-- @param tbl table to change the element of +-- @param key string +-- @param value nil|boolean|number|string|table to set the element to +-- @return value +function Common.set_and_return(tbl, key, value) + tbl[key] = value + return value +end + +--- Writes a table object to a file in json format +-- @tparam string path the path of the file to write include / to use dir +-- @tparam table tbl the table that will be converted to a json string and wrote to file +function Common.write_json(path,tbl) + game.write_file(path,game.table_to_json(tbl)..'\n',true,0) +end + +--- Calls a require that will not error if the file is not found +-- @usage local file = opt_require('file.not.present') -- will not cause any error +-- @tparam string path the path that you want to require +-- @return the returns from that file or nil, error if not loaded +function Common.opt_require(path) + local success, rtn = pcall(require,path) + if success then return rtn + else return nil,rtn end +end + +--- Calls a require and returns only the keys given, file must return a table +-- @usage local extract, param_check = _C.ext_require('expcore.common','extract','param_check') --- @dep expcore.common +-- @tparam string path the path that you want to require +-- @tparam string ... the name of the keys that you want returned +-- @return the keys in the order given +function Common.ext_require(path,...) + local rtn = require(path) + if type(rtn) ~= 'table' then + error('File did not return a table, can not extract keys.',2) + end + return table.extract_keys(rtn,...) +end + +--- Returns a desync safe file path for the current file +-- @tparam[opt=0] number offset the offset in the stack to get, 0 is current file +-- @treturn string the file path +function Common.get_file_path(offset) + offset = offset or 0 + return debug.getinfo(offset+2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) +end + +--- Converts a table to an enum +-- @tparam table tbl table the that will be converted +-- @treturn table the new table that acts like an enum +function Common.enum(tbl) + local rtn = {} + for k,v in pairs(tbl) do + if type(k) ~= 'number' then + rtn[v]=k + end + end + for k,v in pairs(tbl) do + if type(k) == 'number' then + table.insert(rtn,v) + end + end + for k,v in pairs(rtn) do + rtn[v]=k + end + return rtn +end + +--- Returns the closest match to the input +-- @tparam table options table a of options for the auto complete +-- @tparam string input string the input that will be completed +-- @tparam[opt=false] boolean use_key when true the keys of options will be used as the options +-- @tparam[opt=false] boolean rtn_key when true the the key will be returned rather than the value +-- @return the list item found that matches the input +function Common.auto_complete(options,input,use_key,rtn_key) + local rtn = {} + if type(input) ~= 'string' then return end + input = input:lower() + for key,value in pairs(options) do + local check = use_key and key or value + if Common.string_contains(string.lower(check),input) then + local result = rtn_key and key or value + table.insert(rtn,result) + end + end + return rtn[1] +end + +--- Formating. +-- @section formating + +--- Returns a message with valid chat tags to change its colour +-- @tparam string message the message that will be in the output +-- @tparam table color a color which contains r,g,b as its keys +-- @treturn string the message with the color tags included +function Common.format_chat_colour(message,color) + color = color or Colours.white + local color_tag = '[color='..math.round(color.r,3)..','..math.round(color.g,3)..','..math.round(color.b,3)..']' + return string.format('%s%s[/color]',color_tag,message) +end + +--- Returns a message with valid chat tags to change its colour, using localization +-- @tparam ?string|table message the message that will be in the output +-- @tparam table color a color which contains r,g,b as its keys +-- @treturn table the message with the color tags included +function Common.format_chat_colour_localized(message,color) + color = color or Colours.white + color = math.round(color.r,3)..','..math.round(color.g,3)..','..math.round(color.b,3) + return {'color-tag',color,message} +end + +--- Returns the players name in the players color +-- @tparam LuaPlayer player the player to use the name and color of +-- @tparam[opt=false] boolean raw_string when true a is returned rather than a localized string +-- @treturn table the players name with tags for the players color +function Common.format_chat_player_name(player,raw_string) + player = Game.get_player_from_any(player) + local player_name = player and player.name or '' + local player_chat_colour = player and player.chat_color or Colours.white + if raw_string then + return Common.format_chat_colour(player_name,player_chat_colour) + else + return Common.format_chat_colour_localized(player_name,player_chat_colour) + end +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 @@ -91,36 +315,6 @@ function Common.player_return(value,colour,player) else rcon.print(returnAsString) end end ---- Writes a table object to a file in json format --- @tparam string path the path of the file to write include / to use dir --- @tparam table tbl the table that will be converted to a json string and wrote to file -function Common.write_json(path,tbl) - game.write_file(path,game.table_to_json(tbl)..'\n',true,0) -end - ---- Calls a require that will not error if the file is not found --- @usage local file = opt_require('file.not.present') -- will not cause any error --- @tparam string path the path that you want to require --- @return the returns from that file or nil, error if not loaded -function Common.opt_require(path) - local success, rtn = pcall(require,path) - if success then return rtn - else return nil,rtn end -end - ---- Calls a require and returns only the keys given, file must return a table --- @usage local extract, param_check = ext_require('expcore.common','extract','param_check') --- @dep expcore.common --- @tparam string path the path that you want to require --- @tparam string ... the name of the keys that you want returned --- @return the keys in the order given -function Common.ext_require(path,...) - local rtn = require(path) - if type(rtn) ~= 'table' then - error('File did not return a table, can not extract keys.',2) - end - return Common.extract_keys(rtn,...) -end - --- Formats tick into a clean format, denominations from highest to lowest -- long will use words rather than letters -- time will use : separates @@ -213,6 +407,9 @@ function Common.format_time(ticks,options) return rtn end +--- Factorio. +-- @section factorio + --- Moves items to the position and stores them in the closest entity of the type given -- @tparam table items items which are to be added to the chests, ['name']=count -- @tparam[opt=navies] LuaSurface surface the surface that the items will be moved to @@ -416,288 +613,4 @@ function Common.clear_flying_text(surface) end end ---- Tests if a string contains a given substring. --- @tparam string s the string to check for the substring --- @tparam string contains the substring to test for --- @treturn boolean true if the substring was found in the string -function Common.string_contains(s, contains) - return s and string.find(s, contains) ~= nil -end - ---- Extracts certain keys from a table --- @usage local key_three, key_one = extract({key_one='foo',key_two='bar',key_three=true},'key_three','key_one') --- @tparam table tbl table the which contains the keys --- @tparam string ... the names of the keys you want extracted --- @return the keys in the order given -function Common.extract_keys(tbl,...) - local values = {} - for _,key in pairs({...}) do - table.insert(values,tbl[key]) - end - return unpack(values) -end - ---- Converts a table to an enum --- @tparam table tbl table the that will be converted --- @treturn table the new table that acts like an enum -function Common.enum(tbl) - local rtn = {} - for k,v in pairs(tbl) do - if type(k) ~= 'number' then - rtn[v]=k - end - end - for k,v in pairs(tbl) do - if type(k) == 'number' then - table.insert(rtn,v) - end - end - for k,v in pairs(rtn) do - rtn[v]=k - end - return rtn -end - ---- Returns the closest match to the input --- @tparam table options table a of options for the auto complete --- @tparam string input string the input that will be completed --- @tparam[opt=false] boolean use_key when true the keys of options will be used as the options --- @tparam[opt=false] boolean rtn_key when true the the key will be returned rather than the value --- @return the list item found that matches the input -function Common.auto_complete(options,input,use_key,rtn_key) - local rtn = {} - if type(input) ~= 'string' then return end - input = input:lower() - for key,value in pairs(options) do - local check = use_key and key or value - if Common.string_contains(string.lower(check),input) then - local result = rtn_key and key or value - table.insert(rtn,result) - end - end - return rtn[1] -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 function sortFunc(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 to copy the keys from, or an empty table if tbl is nil --- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs() --- @tparam[opt] boolean as_string whether to try and parse the values as strings, or leave them as their existing type --- @treturn array an array with a copy of all the values in the table -function Common.table_values(tbl, sorted, as_string) - if not tbl then return {} end - local valueset = {} - local n = 0 - if as_string then --checking as_string /before/ looping is faster - for _, v in pairs(tbl) do - n = n + 1 - valueset[n] = tostring(v) - end - else - for _, v in pairs(tbl) do - n = n + 1 - valueset[n] = v - end - end - if sorted then - table.sort(valueset,sortFunc) - end - return valueset -end - ---- Returns a copy of all of the keys in the table. --- @tparam table tbl the to copy the keys from, or an empty table if tbl is nil --- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs() --- @tparam[opt] boolean as_string whether to try and parse the keys as strings, or leave them as their existing type --- @treturn array an array with a copy of all the keys in the table -function Common.table_keys(tbl, sorted, as_string) - if not tbl then return {} end - local keyset = {} - local n = 0 - if as_string then --checking as_string /before/ looping is faster - for k, _ in pairs(tbl) do - n = n + 1 - keyset[n] = tostring(k) - end - else - for k, _ in pairs(tbl) do - n = n + 1 - keyset[n] = k - end - end - if sorted then - table.sort(keyset,sortFunc) - end - return keyset -end - ---- Returns the list is a sorted way that would be expected by people (this is by key) --- @tparam table tbl the table to be sorted --- @treturn table the sorted table -function Common.table_alphanumsort(tbl) - local o = Common.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 alternative than above) --- @tparam table tbl the table to be sorted --- @treturn table the sorted table -function Common.table_keysort(tbl) - local o = Common.table_keys(tbl,true) - local _tbl = {} - for _,k in pairs(o) do _tbl[k] = tbl[k] end - return _tbl -end - ---- Returns a message with valid chat tags to change its colour --- @tparam string message the message that will be in the output --- @tparam table color a color which contains r,g,b as its keys --- @treturn string the message with the color tags included -function Common.format_chat_colour(message,color) - color = color or Colours.white - local color_tag = '[color='..math.round(color.r,3)..','..math.round(color.g,3)..','..math.round(color.b,3)..']' - return string.format('%s%s[/color]',color_tag,message) -end - ---- Returns a message with valid chat tags to change its colour, using localization --- @tparam ?string|table message the message that will be in the output --- @tparam table color a color which contains r,g,b as its keys --- @treturn table the message with the color tags included -function Common.format_chat_colour_localized(message,color) - color = color or Colours.white - color = math.round(color.r,3)..','..math.round(color.g,3)..','..math.round(color.b,3) - return {'color-tag',color,message} -end - ---- Returns the players name in the players color --- @tparam LuaPlayer player the player to use the name and color of --- @tparam[opt=false] boolean raw_string when true a is returned rather than a localized string --- @treturn table the players name with tags for the players color -function Common.format_chat_player_name(player,raw_string) - player = Game.get_player_from_any(player) - local player_name = player and player.name or '' - local player_chat_colour = player and player.chat_color or Colours.white - if raw_string then - return Common.format_chat_colour(player_name,player_chat_colour) - else - return Common.format_chat_colour_localized(player_name,player_chat_colour) - end -end - ---- Returns a desync safe file path for the current file --- @tparam[opt=0] number offset the offset in the stack to get, 0 is current file --- @treturn string the file path -function Common.get_file_path(offset) - offset = offset or 0 - return debug.getinfo(offset+2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) -end - ---[[-- Much faster method for inserting items into an array -@tparam table tbl the table that will have the values added to it -@tparam[opt] number start_index the index at which values will be added, nil means end of the array -@tparam table values the new values that will be added to the table -@treturn table the table that was passed as the first argument -@usage-- Adding 1000 values into the middle of the array -local tbl = {} -local values = {} -for i = 1,1000 do tbl[i] = i values[i] = i end -Common.array_insert(tbl,500,values) -- around 0.4ms -]] -function Common.array_insert(tbl,start_index,values) - if not values then - values = start_index - start_index = nil - end - - if start_index then - local starting_length = #tbl - local adding_length = #values - local move_to = start_index+adding_length+1 - for offset = starting_length-start_index, 0, -1 do - tbl[move_to+offset] = tbl[starting_length+offset] - end - start_index = start_index-1 - else - start_index = #tbl - end - - for offset, item in ipairs(values) do - tbl[start_index+offset] = item - end - - return tbl -end - ---[[-- Much faster method for inserting keys into a table -@tparam table tbl the table that will have keys added to it -@tparam[opt] number start_index the index at which values will be added, nil means end of the array, numbered indexs only -@tparam table tbl2 the table that may contain both string and numbered keys -@treturn table the table passed as the first argument -@usage-- Merging two tables -local tbl = {} -local tbl2 = {} -for i = 1,100 do tbl[i] = i tbl['_'..i] = i tbl2[i] = i tbl2['__'..i] = i end -Common.table_insert(tbl,50,tbl2) -]] -function Common.table_insert(tbl,start_index,tbl2) - if not tbl2 then - tbl2 = start_index - start_index = nil - end - - Common.array_insert(tbl,start_index,tbl2) - for key, value in pairs(tbl2) do - if not tonumber(key) then - tbl[key] = value - end - end - - return tbl -end - ---[[-- Used to resolve a value that could also be a function returning that value -@tparam any value the value which you want to test is not nil and if it is a function then call the function -@treturn any the value given or returned by value if it is a function -@usage-- Default value handling --- if default value is not a function then it is returned --- if it is a function then it is called with the first argument being self -local value = Common.resolve_value(self.defaut_value,self) -]] -function Common.resolve_value(value,...) - if value then - if type(value) == 'function' then - return value(...) - else - return value - end - end -end - return Common \ No newline at end of file diff --git a/expcore/roles.lua b/expcore/roles.lua index 1163d84b..11616822 100644 --- a/expcore/roles.lua +++ b/expcore/roles.lua @@ -117,8 +117,8 @@ local Global = require 'utils.global' --- @dep utils.global local Event = require 'utils.event' --- @dep utils.event local Groups = require 'expcore.permission_groups' --- @dep expcore.permission_groups local Async = require 'expcore.async' --- @dep expcore.async -local Colours = require 'resources.color_presets' --- @dep resources.color_presets -local write_json = ext_require('expcore.common','write_json') --- @dep expcore.common +local Colours = require 'utils.color_presets' --- @dep utils.color_presets +local write_json = _C.ext_require('expcore.common','write_json') --- @dep expcore.common local Roles = { _prototype={}, @@ -437,7 +437,7 @@ function Roles.define_role_order(order) end end -- Check no roles were missed - for role_name,_ in pairs(Role.config.roles) do + for role_name,_ in pairs(Roles.config.roles) do if not done[role_name] then error('Role missing '..role_name..' from role order, all defined roles must be included.',2) end diff --git a/modules/addons/death-logger.lua b/modules/addons/death-logger.lua index fb188f82..6f4be5d7 100644 --- a/modules/addons/death-logger.lua +++ b/modules/addons/death-logger.lua @@ -5,7 +5,7 @@ local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global local config = require 'config.death_logger' --- @dep config.death_logger -local format_time,move_items = ext_require('expcore.common','format_time','move_items') --- @dep expcore.common +local format_time,move_items = _C.ext_require('expcore.common','format_time','move_items') --- @dep expcore.common local deaths = { archive={} -- deaths moved here after body is gone diff --git a/modules/addons/discord-alerts.lua b/modules/addons/discord-alerts.lua index 5aabc77e..22bba566 100644 --- a/modules/addons/discord-alerts.lua +++ b/modules/addons/discord-alerts.lua @@ -3,8 +3,8 @@ local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game -local Colors = require 'resources.color_presets' --- @dep resources.color_presets -local write_json,format_time = ext_require('expcore.common','write_json','format_time') --- @dep expcore.common +local Colors = require 'utils.color_presets' --- @dep utils.color_presets +local write_json,format_time = _C.ext_require('expcore.common','write_json','format_time') --- @dep expcore.common local config = require 'config.discord_alerts' --- @dep config.discord_alerts local function get_player_name(event) diff --git a/modules/addons/greetings.lua b/modules/addons/greetings.lua index df625656..068e33e7 100644 --- a/modules/addons/greetings.lua +++ b/modules/addons/greetings.lua @@ -4,7 +4,7 @@ local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.event local config = require 'config.join_messages' --- @dep config.join_messages local Global = require 'utils.global' --- @dep utils.global -require 'utils.table' +require 'overrides.table' Global.register(config,function(tbl) config = tbl diff --git a/modules/addons/random-player-colours.lua b/modules/addons/random-player-colours.lua index 0677faa1..30526f20 100644 --- a/modules/addons/random-player-colours.lua +++ b/modules/addons/random-player-colours.lua @@ -1,12 +1,12 @@ --- Gives players random colours when they join, also applies preset colours to those who have them -- @addon Player-Colours -local Colours = require 'resources.color_presets' --- @dep resources.color_presets +local Colours = require 'utils.color_presets' --- @dep utils.color_presets local Game = require 'utils.game' --- @dep utils.game local Event = require 'utils.event' --- @dep utils.event local config = require 'config.preset_player_colours' --- @dep config.preset_player_colours local Global = require 'utils.global' --- @dep utils.global -require 'utils.table' +require 'overrides.table' Global.register(config,function(tbl) config = tbl diff --git a/modules/addons/scorched-earth.lua b/modules/addons/scorched-earth.lua index 82c361de..9ae946f5 100644 --- a/modules/addons/scorched-earth.lua +++ b/modules/addons/scorched-earth.lua @@ -4,7 +4,7 @@ local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global -local print_grid_value, clear_flying_text = ext_require('expcore.common','print_grid_value','clear_flying_text') --- @dep expcore.common +local print_grid_value, clear_flying_text = _C.ext_require('expcore.common','print_grid_value','clear_flying_text') --- @dep expcore.common local config = require 'config.scorched_earth' --- @dep config.scorched_earth -- Loops over the config and finds the wile which has the highest value for strength diff --git a/modules/commands/admin-chat.lua b/modules/commands/admin-chat.lua index 63a5447d..9a8182cb 100644 --- a/modules/commands/admin-chat.lua +++ b/modules/commands/admin-chat.lua @@ -4,7 +4,7 @@ ]] local Commands = require 'expcore.commands' --- @dep expcore.commands -local format_chat_player_name = ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common +local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common require 'config.expcore-commands.parse_general' --- Sends a message in chat that only admins can see diff --git a/modules/commands/clear-inventory.lua b/modules/commands/clear-inventory.lua index 587e8ce2..91e6c7e5 100644 --- a/modules/commands/clear-inventory.lua +++ b/modules/commands/clear-inventory.lua @@ -4,7 +4,7 @@ ]] local Commands = require 'expcore.commands' --- @dep expcore.commands -local move_items = ext_require('expcore.common','move_items') --- @dep expcore.common +local move_items = _C.ext_require('expcore.common','move_items') --- @dep expcore.common require 'config.expcore-commands.parse_roles' --- Clears a players inventory diff --git a/modules/commands/jail.lua b/modules/commands/jail.lua index c6c92954..279eb373 100644 --- a/modules/commands/jail.lua +++ b/modules/commands/jail.lua @@ -5,7 +5,7 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Jail = require 'modules.control.jail' --- @dep modules.control.jail -local format_chat_player_name = ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common +local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common require 'config.expcore-commands.parse_roles' --- Puts a player into jail and removes all other roles. diff --git a/modules/commands/rainbow.lua b/modules/commands/rainbow.lua index a5c03e53..4a29fe6a 100644 --- a/modules/commands/rainbow.lua +++ b/modules/commands/rainbow.lua @@ -4,7 +4,7 @@ ]] local Commands = require 'expcore.commands' --- @dep expcore.commands -local format_chat_colour = ext_require('expcore.common','format_chat_colour') --- @dep expcore.common +local format_chat_colour = _C.ext_require('expcore.common','format_chat_colour') --- @dep expcore.common local function step_component(c1,c2) if c1 < 0 then diff --git a/modules/commands/reports.lua b/modules/commands/reports.lua index 8baaf5f3..51f2f493 100644 --- a/modules/commands/reports.lua +++ b/modules/commands/reports.lua @@ -6,7 +6,7 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles local Commands = require 'expcore.commands' --- @dep expcore.commands local Reports = require 'modules.control.reports' --- @dep modules.control.reports -local format_chat_player_name = ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common +local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common require 'config.expcore-commands.parse_general' --- Reports a player and notifies moderators diff --git a/modules/commands/roles.lua b/modules/commands/roles.lua index 63575732..448109f0 100644 --- a/modules/commands/roles.lua +++ b/modules/commands/roles.lua @@ -5,8 +5,8 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Roles = require 'expcore.roles' --- @dep expcore.roles -local Colours = require 'resources.color_presets' --- @dep resources.color_presets -local format_chat_player_name, format_chat_colour_localized = ext_require('expcore.common', +local Colours = require 'utils.color_presets' --- @dep utils.color_presets +local format_chat_player_name, format_chat_colour_localized = _C.ext_require('expcore.common', 'format_chat_player_name', 'format_chat_colour_localized' ) diff --git a/modules/commands/warnings.lua b/modules/commands/warnings.lua index 2cd5509c..9c1dfcef 100644 --- a/modules/commands/warnings.lua +++ b/modules/commands/warnings.lua @@ -5,7 +5,7 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Warnings = require 'modules.control.warnings' --- @dep modules.control.warnings -local format_chat_player_name = ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common +local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common local config = require 'config.warnings' --- @dep config.warnings require 'config.expcore-commands.parse_roles' diff --git a/modules/control/jail.lua b/modules/control/jail.lua index 89c9043c..10a387a1 100644 --- a/modules/control/jail.lua +++ b/modules/control/jail.lua @@ -23,7 +23,7 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global -local move_items = ext_require('expcore.common','move_items') --- @dep expcore.common +local move_items = _C.ext_require('expcore.common','move_items') --- @dep expcore.common local valid_player = Game.get_player_from_any local assign_roles = Roles.assign_player diff --git a/modules/control/production.lua b/modules/control/production.lua index d12c8477..16eb97b9 100644 --- a/modules/control/production.lua +++ b/modules/control/production.lua @@ -32,8 +32,8 @@ ]] -local Colors = require 'resources.color_presets' --- @dep resources.color_presets -local format_number = ext_require('util','format_number') --- @dep util +local Colors = require 'utils.color_presets' --- @dep utils.color_presets +local format_number = _C.ext_require('util','format_number') --- @dep util local precision_index = defines.flow_precision_index local Production = {} diff --git a/modules/control/warps.lua b/modules/control/warps.lua index 8958c833..93bf0ea2 100644 --- a/modules/control/warps.lua +++ b/modules/control/warps.lua @@ -25,7 +25,6 @@ local Store = require 'expcore.store' --- @dep expcore.store local Global = require 'utils.global' --- @dep utils.global local Token = require 'utils.token' --- @dep utils.token local config = require 'config.warps' --- @dep config.warps -local table_values,table_keysort = ext_require('expcore.common','table_values','table_keysort') --- @dep expcore.common local Warps = {} @@ -64,7 +63,7 @@ Store.watch(warp_store,function(warp,warp_id) end -- Sort the warp names in alphabetical order - local new_warp_ids = table_values(table_keysort(warp_names)) + local new_warp_ids = table.get_values(table.keysort(warp_names)) table.insert(new_warp_ids,1,spawn_id) new_warp_ids.spawn = spawn_id force_warps[force_name] = new_warp_ids diff --git a/modules/gui/debug/_g_view.lua b/modules/gui/debug/_g_view.lua index 33005bd2..2cf7490a 100644 --- a/modules/gui/debug/_g_view.lua +++ b/modules/gui/debug/_g_view.lua @@ -1,6 +1,6 @@ local Gui = require 'utils.gui' --- @dep utils.gui local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model -local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Color = require 'utils.color_presets' --- @dep utils.color_presets local dump = Model.dump diff --git a/modules/gui/debug/event_view.lua b/modules/gui/debug/event_view.lua index cae93e60..b56cb34f 100644 --- a/modules/gui/debug/event_view.lua +++ b/modules/gui/debug/event_view.lua @@ -1,5 +1,5 @@ local Event = require 'utils.event' -local table = require 'utils.table' +local table = require 'overrides.table' local Gui = require 'utils.gui' local Model = require 'modules.gui.debug.model' diff --git a/modules/gui/debug/expcore_gui_view.lua b/modules/gui/debug/expcore_gui_view.lua index cf95e894..468196e4 100644 --- a/modules/gui/debug/expcore_gui_view.lua +++ b/modules/gui/debug/expcore_gui_view.lua @@ -1,6 +1,6 @@ local Gui = require 'utils.gui' --- @dep utils.gui local ExpGui = require 'expcore.gui' --- @dep utils.global -local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Color = require 'utils.color_presets' --- @dep utils.color_presets local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model local dump = Model.dump diff --git a/modules/gui/debug/expcore_store_view.lua b/modules/gui/debug/expcore_store_view.lua index 300acc2d..36ab8027 100644 --- a/modules/gui/debug/expcore_store_view.lua +++ b/modules/gui/debug/expcore_store_view.lua @@ -1,6 +1,6 @@ local Gui = require 'utils.gui' --- @dep utils.gui local Store = require 'expcore.store' --- @dep utils.global -local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Color = require 'utils.color_presets' --- @dep utils.color_presets local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model local dump = Model.dump diff --git a/modules/gui/debug/global_view.lua b/modules/gui/debug/global_view.lua index df057c47..3ab51d8d 100644 --- a/modules/gui/debug/global_view.lua +++ b/modules/gui/debug/global_view.lua @@ -1,6 +1,6 @@ local Gui = require 'utils.gui' --- @dep utils.gui local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model -local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Color = require 'utils.color_presets' --- @dep utils.color_presets local dump = Model.dump local dump_text = Model.dump_text diff --git a/modules/gui/debug/main_view.lua b/modules/gui/debug/main_view.lua index 9807329c..0771bdb1 100644 --- a/modules/gui/debug/main_view.lua +++ b/modules/gui/debug/main_view.lua @@ -1,5 +1,5 @@ local Gui = require 'utils.gui' --- @dep utils.gui -local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Color = require 'utils.color_presets' --- @dep utils.color_presets local Public = {} diff --git a/modules/gui/debug/model.lua b/modules/gui/debug/model.lua index ff120941..101ba30b 100644 --- a/modules/gui/debug/model.lua +++ b/modules/gui/debug/model.lua @@ -1,5 +1,5 @@ local Gui = require 'utils.gui' --- @dep utils.gui -local table = require 'utils.table' --- @dep utils.table +local table = require 'overrides.table' --- @dep overrides.table local gui_names = Gui.names local type = type diff --git a/modules/gui/debug/package_view.lua b/modules/gui/debug/package_view.lua index f29aafbb..292bf9d7 100644 --- a/modules/gui/debug/package_view.lua +++ b/modules/gui/debug/package_view.lua @@ -1,5 +1,5 @@ local Gui = require 'utils.gui' --- @dep utils.gui -local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Color = require 'utils.color_presets' --- @dep utils.color_presets local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model local dump_function = Model.dump_function @@ -17,9 +17,9 @@ local ignore = { math = true, debug = true, serpent = true, - ['utils.math'] = true, + ['overrides.math'] = true, util = true, - ['utils.inspect'] = true, + ['overrides.inspect'] = true, ['mod-gui'] = true } diff --git a/modules/gui/debug/redmew_global_view.lua b/modules/gui/debug/redmew_global_view.lua index a62a6151..4bff705f 100644 --- a/modules/gui/debug/redmew_global_view.lua +++ b/modules/gui/debug/redmew_global_view.lua @@ -1,7 +1,7 @@ local Gui = require 'utils.gui' --- @dep utils.gui local Global = require 'utils.global' --- @dep utils.global local Token = require 'utils.token' --- @dep utils.token -local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Color = require 'utils.color_presets' --- @dep utils.color_presets local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model local dump = Model.dump diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 0c460eb7..beecb309 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -9,9 +9,9 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles local Store = require 'expcore.store' --- @dep expcore.store local Game = require 'utils.game' --- @dep utils.game local Event = require 'utils.event' --- @dep utils.event -local format_time = ext_require('expcore.common','format_time') --- @dep expcore.common +local format_time = _C.ext_require('expcore.common','format_time') --- @dep expcore.common local config = require 'config.action_buttons' --- @dep config.action_buttons -local Colors = require 'resources.color_presets' --- @dep resources.color_presets +local Colors = require 'utils.color_presets' --- @dep utils.color_presets -- Stores the name of the player a player has selected local selected_player_store = Store.register(function(player) diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index f2384a21..197699fc 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -8,8 +8,8 @@ local Gui = require 'expcore.gui' --- @dep expcore.gui local Roles = require 'expcore.roles' --- @dep expcore.roles local Event = require 'utils.event' --- @dep utils.event local config = require 'config.rockets' --- @dep config.rockets -local format_time = ext_require('expcore.common','format_time') --- @dep expcore.common -local Colors = require 'resources.color_presets' --- @dep resources.color_presets +local format_time = _C.ext_require('expcore.common','format_time') --- @dep expcore.common +local Colors = require 'utils.color_presets' --- @dep utils.color_presets local Rockets = require 'modules.control.rockets' --- @dep modules.control.rockets local time_formats = { diff --git a/modules/gui/science-info.lua b/modules/gui/science-info.lua index 36d4d947..9c6b794f 100644 --- a/modules/gui/science-info.lua +++ b/modules/gui/science-info.lua @@ -7,7 +7,7 @@ local Gui = require 'expcore.gui' --- @dep expcore.gui local Roles = require 'expcore.roles' --- @dep expcore.gui local Event = require 'utils.event' --- @dep utils.event -local format_time = ext_require('expcore.common','format_time') --- @dep expcore.common +local format_time = _C.ext_require('expcore.common','format_time') --- @dep expcore.common local config = require 'config.science' --- @dep config.science local Production = require 'modules.control.production' --- @dep modules.control.production diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index b8b260b0..702f3499 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -8,8 +8,8 @@ local Gui = require 'expcore.gui' --- @dep expcore.gui local Event = require 'utils.event' --- @dep utils.event local Roles = require 'expcore.roles' --- @dep expcore.roles local config = require 'config.tasks' --- @dep config.tasks -local format_time,table_keys = ext_require('expcore.common','format_time','table_keys') --- @dep expcore.common local Tasks = require 'modules.control.tasks' --- @dep modules.control.tasks +local format_time = _C.format_time --- @dep expcore.common -- Styles used for sprite buttons local Styles = { @@ -223,7 +223,7 @@ end) local function update_task(player,task_table,task_id) local task = Tasks.get_task(task_id) local task_ids = Tasks.get_force_task_ids(player.force.name) - local task_number = table.index_of(task_ids, task_id) + local task_number = table.get_index(task_ids, task_id) -- Task no longer exists so should be removed from the list if not task then @@ -240,7 +240,7 @@ local function update_task(player,task_table,task_id) -- Update the edit flow local edit_flow = task_table['edit-'..task_id] local player_allowed_edit = check_player_permissions(player,task) - local players_editing = table_keys(task.curently_editing) + local players_editing = table.get_keys(task.curently_editing) local edit_task_element = edit_flow[edit_task.name] local discard_task_element = edit_flow[discard_task.name] diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index de92d42e..52b711da 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -10,10 +10,10 @@ local Global = require 'utils.global' --- @dep utils.global local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game local Roles = require 'expcore.roles' --- @dep expcore.roles -local Colors = require 'resources.color_presets' --- @dep resources.color_presets +local Colors = require 'utils.color_presets' --- @dep utils.color_presets local config = require 'config.warps' --- @dep config.warps -local format_time,table_keys = ext_require('expcore.common','format_time','table_keys') --- @dep expcore.common local Warps = require 'modules.control.warps' --- @dep modules.control.warps +local format_time = _C.format_time --- @dep expcore.common -- Stores a boolean value indexed by player name local player_in_range_store = Store.register(function(player) @@ -319,7 +319,7 @@ local function update_warp(player,warp_table,warp_id) -- Update the edit flow local edit_flow = warp_table['edit-'..warp_id] local player_allowed_edit = check_player_permissions(player,'allow_edit_warp',warp) - local players_editing = table_keys(warp.currently_editing) + local players_editing = table.get_keys(warp.currently_editing) local edit_warp_element = edit_flow[edit_warp.name] local discard_warp_element = edit_flow[discard_warp.name] diff --git a/utils/debug.lua b/overrides/debug.lua similarity index 99% rename from utils/debug.lua rename to overrides/debug.lua index 98f85a28..20be17a8 100644 --- a/utils/debug.lua +++ b/overrides/debug.lua @@ -161,4 +161,4 @@ function Debug.is_closure(func) end end -return Debug +return Debug \ No newline at end of file diff --git a/utils/inspect.lua b/overrides/inspect.lua similarity index 99% rename from utils/inspect.lua rename to overrides/inspect.lua index c13a8cd4..76605169 100644 --- a/utils/inspect.lua +++ b/overrides/inspect.lua @@ -338,5 +338,4 @@ end setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end }) -return inspect - +return inspect \ No newline at end of file diff --git a/utils/math.lua b/overrides/math.lua similarity index 99% rename from utils/math.lua rename to overrides/math.lua index 179005c9..a9ba046f 100644 --- a/utils/math.lua +++ b/overrides/math.lua @@ -52,4 +52,4 @@ math.degrees = function(angle) return angle * deg_to_rad end -return math +return math \ No newline at end of file diff --git a/utils/print_override.lua b/overrides/print.lua similarity index 69% rename from utils/print_override.lua rename to overrides/print.lua index 848c91b2..22f3c72a 100644 --- a/utils/print_override.lua +++ b/overrides/print.lua @@ -1,5 +1,4 @@ -local Public = {} - +--luacheck:ignore global print local locale_string = {'', '[PRINT] ', nil} local raw_print = print @@ -8,6 +7,4 @@ function print(str) log(locale_string) end -Public.raw_print = raw_print - -return Public +return raw_print \ No newline at end of file diff --git a/utils/require_override.lua b/overrides/require.lua similarity index 75% rename from utils/require_override.lua rename to overrides/require.lua index 06779e59..36430248 100644 --- a/utils/require_override.lua +++ b/overrides/require.lua @@ -1,4 +1,5 @@ -local loaded = _G.package.loaded +--luacheck:ignore global require +local loaded = package.loaded local raw_require = require function require(path) diff --git a/resources/data_stages.lua b/overrides/stages.lua similarity index 91% rename from resources/data_stages.lua rename to overrides/stages.lua index 516fb321..8a7fb800 100644 --- a/resources/data_stages.lua +++ b/overrides/stages.lua @@ -10,3 +10,5 @@ _STAGE = { --config_change = 7, runtime = 8 } + +_LIFECYCLE = _STAGE.control \ No newline at end of file diff --git a/utils/table.lua b/overrides/table.lua similarity index 55% rename from utils/table.lua rename to overrides/table.lua index 4b1973e2..e3823302 100644 --- a/utils/table.lua +++ b/overrides/table.lua @@ -22,7 +22,7 @@ end -- The catch is that fast_remove doesn't guarantee to maintain the order of items in the array. -- @param tbl arrayed table -- @param index Must be >= 0. The case where index > #tbl is handled. -function table.fast_remove(tbl, index) +function table.remove_index(tbl, index) local count = #tbl if index > count then return @@ -36,7 +36,7 @@ end --- Adds the contents of table t2 to table t1 -- @param t1
    to insert into -- @param t2
    to insert from -function table.add_all(t1, t2) +function table.merge_table(t1, t2) for k, v in pairs(t2) do if tonumber(k) then t1[#t1 + 1] = v @@ -46,11 +46,74 @@ function table.add_all(t1, t2) end end +--[[-- Much faster method for inserting items into an array +@tparam table tbl the table that will have the values added to it +@tparam[opt] number start_index the index at which values will be added, nil means end of the array +@tparam table values the new values that will be added to the table +@treturn table the table that was passed as the first argument +@usage-- Adding 1000 values into the middle of the array +local tbl = {} +local values = {} +for i = 1,1000 do tbl[i] = i values[i] = i end +table.array_insert(tbl,500,values) -- around 0.4ms +]] +function table.array_insert(tbl,start_index,values) + if not values then + values = start_index + start_index = nil + end + + if start_index then + local starting_length = #tbl + local adding_length = #values + local move_to = start_index+adding_length+1 + for offset = starting_length-start_index, 0, -1 do + tbl[move_to+offset] = tbl[starting_length+offset] + end + start_index = start_index-1 + else + start_index = #tbl + end + + for offset, item in ipairs(values) do + tbl[start_index+offset] = item + end + + return tbl +end + +--[[-- Much faster method for inserting keys into a table +@tparam table tbl the table that will have keys added to it +@tparam[opt] number start_index the index at which values will be added, nil means end of the array, numbered indexs only +@tparam table tbl2 the table that may contain both string and numbered keys +@treturn table the table passed as the first argument +@usage-- Merging two tables +local tbl = {} +local tbl2 = {} +for i = 1,100 do tbl[i] = i tbl['_'..i] = i tbl2[i] = i tbl2['__'..i] = i end +table.table_insert(tbl,50,tbl2) +]] +function table.table_insert(tbl,start_index,tbl2) + if not tbl2 then + tbl2 = start_index + start_index = nil + end + + table.array_insert(tbl,start_index,tbl2) + for key, value in pairs(tbl2) do + if not tonumber(key) then + tbl[key] = value + end + end + + return tbl +end + --- Checks if a table contains an element -- @param t
    -- @param e table element -- @return the index of the element or nil -function table.index_of(t, e) +function table.get_key(t, e) for k, v in pairs(t) do if v == e then return k @@ -63,7 +126,7 @@ end -- @param t
    -- @param e table element -- @return the index of the element or nil -function table.index_of_in_array(t, e) +function table.get_index(t, e) for i = 1, #t do if t[i] == e then return i @@ -72,22 +135,33 @@ function table.index_of_in_array(t, e) return nil end -local index_of = table.index_of --- Checks if a table contains an element -- @param t
    -- @param e table element -- @return indicating success function table.contains(t, e) - return index_of(t, e) and true or false + return table.get_key(t, e) and true or false end -local index_of_in_array = table.index_of_in_array --- Checks if the arrayed portion of a table contains an element -- @param t
    -- @param e table element -- @return indicating success function table.array_contains(t, e) - return index_of_in_array(t, e) and true or false + return table.get_index(t, e) and true or false +end + +--- Extracts certain keys from a table +-- @usage local key_three, key_one = extract({key_one='foo',key_two='bar',key_three=true},'key_three','key_one') +-- @tparam table tbl table the which contains the keys +-- @tparam string ... the names of the keys you want extracted +-- @return the keys in the order given +function table.extract_keys(tbl,...) + local values = {} + for _,key in pairs({...}) do + table.insert(values,tbl[key]) + end + return unpack(values) end --- Adds an element into a specific index position while shuffling the rest down @@ -151,6 +225,21 @@ function table.get_random_weighted(weighted_table, item_index, weight_index) end end +--- Clears all existing entries in a table +-- @param t
    to clear +-- @param array to indicate whether the table is an array or not +function table.clear_table(t, array) + if array then + for i = 1, #t do + t[i] = nil + end + else + for i in pairs(t) do + t[i] = nil + end + end +end + --- Creates a fisher-yates shuffle of a sequential number-indexed table -- because this uses math.random, it cannot be used outside of events if no rng is supplied -- from: http://www.sdknews.com/cross-platform/corona/tutorial-how-to-shuffle-table-items @@ -171,19 +260,102 @@ function table.shuffle_table(t, rng) end end ---- Clears all existing entries in a table --- @param t
    to clear --- @param array to indicate whether the table is an array or not -function table.clear_table(t, array) - if array then - for i = 1, #t do - t[i] = nil +--- 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 function sortFunc(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 to copy the keys from, or an empty table if tbl is nil +-- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs() +-- @tparam[opt] boolean as_string whether to try and parse the values as strings, or leave them as their existing type +-- @treturn array an array with a copy of all the values in the table +function table.get_values(tbl, sorted, as_string) + if not tbl then return {} end + local valueset = {} + local n = 0 + if as_string then --checking as_string /before/ looping is faster + for _, v in pairs(tbl) do + n = n + 1 + valueset[n] = tostring(v) end else - for i in pairs(t) do - t[i] = nil + for _, v in pairs(tbl) do + n = n + 1 + valueset[n] = v end end + if sorted then + table.sort(valueset,sortFunc) + end + return valueset +end + +--- Returns a copy of all of the keys in the table. +-- @tparam table tbl the to copy the keys from, or an empty table if tbl is nil +-- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs() +-- @tparam[opt] boolean as_string whether to try and parse the keys as strings, or leave them as their existing type +-- @treturn array an array with a copy of all the keys in the table +function table.get_keys(tbl, sorted, as_string) + if not tbl then return {} end + local keyset = {} + local n = 0 + if as_string then --checking as_string /before/ looping is faster + for k, _ in pairs(tbl) do + n = n + 1 + keyset[n] = tostring(k) + end + else + for k, _ in pairs(tbl) do + n = n + 1 + keyset[n] = k + end + end + if sorted then + table.sort(keyset,sortFunc) + end + return keyset +end + +--- Returns the list is a sorted way that would be expected by people (this is by key) +-- @tparam table tbl the table to be sorted +-- @treturn table the sorted table +function table.alphanumsort(tbl) + local o = table.get_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 alternative than above) +-- @tparam table tbl the table to be sorted +-- @treturn table the sorted table +function table.keysort(tbl) + local o = table.get_keys(tbl,true) + local _tbl = {} + for _,k in pairs(o) do _tbl[k] = tbl[k] end + return _tbl end --[[ @@ -238,7 +410,7 @@ require 'util' -- process is a function which allow altering the passed object before transforming it into a string. -- A typical way to use it would be to remove certain values so that they don't appear at all. -- return the prettied table -table.inspect = require 'utils.inspect' --- @dep utils.inspect +table.inspect = require 'overrides.inspect' --- @dep overrides.inspect --- Takes a table and returns the number of entries in the table. (Slower than #table, faster than iterating via pairs) table.size = table_size @@ -262,4 +434,4 @@ table.merge = util.merge -- @return table.equals = table.compare -return table +return table \ No newline at end of file diff --git a/resources/version.lua b/resources/version.lua deleted file mode 100644 index 98d7ac58..00000000 --- a/resources/version.lua +++ /dev/null @@ -1,2 +0,0 @@ -global.redmew_version = nil -global.expgaming_version = '5.0.0' \ No newline at end of file diff --git a/utils/alien_evolution_progress.lua b/utils/alien_evolution_progress.lua deleted file mode 100644 index 03c97aa0..00000000 --- a/utils/alien_evolution_progress.lua +++ /dev/null @@ -1,179 +0,0 @@ ---[[-- info - Original (javascript) version: https://hastebin.com/udakacavap.js - Can be tested against: https://wiki.factorio.com/Enemies#Spawn_chances_by_evolution_factor -]] - --- dependencies -local Global = require 'utils.global' --- @dep utils.global -local Debug = require 'utils.debug' --- @dep utils.debug -local table = require 'utils.table' --- @dep utils.table - --- localized functions -local get_random_weighted = table.get_random_weighted -local round = math.round -local ceil = math.ceil -local floor = math.floor -local random = math.random -local pairs = pairs -local format = string.format - --- this -local AlienEvolutionProgress = {} - -local memory = { - spawner_specifications = {}, - spawner_specifications_count = 0, - evolution_cache = { - ['biter-spawner'] = { - evolution = -1, - weight_table = {}, - }, - ['spitters-spawner'] = { - evolution = -1, - weight_table = {}, - }, - }, -} - -Global.register_init({ - memory = memory, -}, function(tbl) - for name, prototype in pairs(game.entity_prototypes) do - if prototype.type == 'unit-spawner' and prototype.subgroup.name == 'enemies' then - tbl.memory.spawner_specifications[name] = prototype.result_units - memory.spawner_specifications_count = memory.spawner_specifications_count + 1 - end - end -end, function(tbl) - memory = tbl.memory -end) - -local function lerp(low, high, pos) - local s = high.evolution_factor - low.evolution_factor; - local l = (pos - low.evolution_factor) / s; - return (low.weight * (1 - l)) + (high.weight * l) -end - -local function get_values(map, evolution_factor) - local result = {} - local sum = 0 - - for _, spawner_data in pairs(map) do - local list = spawner_data.spawn_points; - local low = list[1]; - local high = list[#list]; - - for _, val in pairs(list) do - local val_evolution = val.evolution_factor - if val_evolution <= evolution_factor and val_evolution > low.evolution_factor then - low = val; - end - if val_evolution >= evolution_factor and val_evolution < high.evolution_factor then - high = val - end - end - - local val - if evolution_factor <= low.evolution_factor then - val = low.weight - elseif evolution_factor >= high.evolution_factor then - val = high.weight; - else - val = lerp(low, high, evolution_factor) - end - sum = sum + val; - - result[spawner_data.unit] = val; - end - - local weighted_table = {} - local count = 0 - for index, _ in pairs(result) do - count = count + 1 - weighted_table[count] = {index, result[index] / sum} - end - - return weighted_table; -end - -local function get_spawner_values(spawner, evolution) - local spawner_specification = memory.spawner_specifications[spawner] - if not spawner_specification then - Debug.print(format('Spawner "%s" does not exist in the prototype data', spawner)) - return - end - - local cache = memory.evolution_cache[spawner] - - if not cache then - cache = { - evolution = -1, - weight_table = {}, - } - memory.evolution_cache[spawner] = cache - end - - local evolution_value = round(evolution * 100) - if (cache.evolution < evolution_value) then - cache.evolution = evolution_value - cache.weight_table = get_values(spawner_specification, evolution) - end - - return cache.weight_table -end - -local function calculate_total(count, spawner, evolution) - if count == 0 then - return {} - end - - local spawner_values = get_spawner_values(spawner, evolution) - if not spawner_values then - return {} - end - - local aliens = {} - for _ = 1, count do - local name = get_random_weighted(spawner_values) - aliens[name] = (aliens[name] or 0) + 1 - end - - return aliens -end - ----Creates the spawner_request structure required for AlienEvolutionProgress.get_aliens for all ----available spawner's. If dividing the total spawner's by the total aliens causes a fraction, the ----fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on both. ----@param total_aliens table -function AlienEvolutionProgress.create_spawner_request(total_aliens) - local per_spawner = total_aliens / memory.spawner_specifications_count - local fraction = per_spawner % 1 - - local spawner_request = {} - for spawner, _ in pairs(memory.spawner_specifications) do - local count = per_spawner - if fraction > 0 then - if random() > fraction then - count = ceil(count) - else - count = floor(count) - end - end - spawner_request[spawner] = count - end - - return spawner_request -end - -function AlienEvolutionProgress.get_aliens(spawner_requests, evolution) - local aliens = {} - for spawner, count in pairs(spawner_requests) do - for name, amount in pairs(calculate_total(count, spawner, evolution)) do - aliens[name] = (aliens[name] or 0) + amount - end - end - - return aliens -end - -return AlienEvolutionProgress diff --git a/resources/color_presets.lua b/utils/color_presets.lua similarity index 100% rename from resources/color_presets.lua rename to utils/color_presets.lua diff --git a/utils/command.lua b/utils/command.lua deleted file mode 100644 index 692eb285..00000000 --- a/utils/command.lua +++ /dev/null @@ -1,326 +0,0 @@ -local Event = require 'utils.event' --- @dep utils.event -local Game = require 'utils.game' --- @dep utils.game -local Utils = require 'utils.core' --- @dep utils.core -local Timestamp = require 'utils.timestamp' --- @dep utils.timestamp -local Rank = require 'features.rank_system' --- @dep features.rank_system -local Donator = require 'features.donator' --- @dep features.donator -local Server = require 'features.server' --- @dep features.server -local Ranks = require 'resources.ranks' --- @dep resources.ranks - -local insert = table.insert -local format = string.format -local next = next -local serialize = serpent.line -local match = string.match -local gmatch = string.gmatch -local get_rank_name = Rank.get_rank_name - -local Command = {} - -local deprecated_command_alternatives = { - ['silent-command'] = 'sc', - ['tpplayer'] = 'tp ', - ['tppos'] = 'tp', - ['tpmode'] = 'tp mode', - ['color-redmew'] = 'redmew-color' -} - -local notify_on_commands = { - ['version'] = 'RedMew has a version as well, accessible via /redmew-version', - ['color'] = 'RedMew allows color saving and a color randomiser: check out /redmew-color', - ['ban'] = 'In case your forgot: please remember to include a message on how to appeal a ban' -} - -local option_names = { - ['description'] = 'A description of the command', - ['arguments'] = 'A table of arguments, example: {"foo", "bar"} would map the first 2 arguments to foo and bar', - ['default_values'] = 'A default value for a given argument when omitted, example: {bar = false}', - ['required_rank'] = 'Set this to determines what rank is required to execute a command', - ['donator_only'] = 'Set this to true if only donators may execute this command', - ['debug_only'] = 'Set this to true if it should be registered when _DEBUG is true', - ['cheat_only'] = 'Set this to true if it should be registered when _CHEATS is true', - ['allowed_by_server'] = 'Set to true if the server (host) may execute this command', - ['allowed_by_player'] = 'Set to false to disable players from executing this command', - ['log_command'] = 'Set to true to log commands. Always true when admin is required', - ['capture_excess_arguments'] = 'Allows the last argument to be the remaining text in the command', - ['custom_help_text'] = 'Sets a custom help text to override the auto-generated help', -} - ----Validates if there aren't any wrong fields in the options. ----@param command_name string ----@param options table -local function assert_existing_options(command_name, options) - local invalid = {} - for name, _ in pairs(options) do - if not option_names[name] then - insert(invalid, name) - end - end - - if next(invalid) then - error(format("The following options were given to the command '%s' but are invalid: %s", command_name, serialize(invalid))) - end -end - ----Adds a command to be executed. ---- ----Options table accepts the following structure: { ---- description = 'A description of the command', ---- arguments = {'foo', 'bar'}, -- maps arguments to these names in the given sequence ---- default_values = {bar = false}, -- gives a default value to 'bar' when omitted ---- required_rank = Ranks.regular, -- defaults to Ranks.guest ---- donator_only = true, -- defaults to false ---- debug_only = true, -- registers the command if _DEBUG is set to true, defaults to false ---- cheat_only = true, -- registers the command if _CHEATS is set to true, defaults to false ---- allowed_by_server = true, -- lets the server execute this, defaults to false ---- allowed_by_player = false, -- lets players execute this, defaults to true ---- log_command = true, -- defaults to false unless admin only, then always true ---- capture_excess_arguments = true, -- defaults to false, captures excess arguments in the last argument, useful for sentences ----} ---- ----The callback receives the following arguments: ---- - arguments (indexed by name, value is extracted from the parameters) ---- - the LuaPlayer or nil if it doesn't exist (such as the server player) ---- - the game tick in which the command was executed ---- ----@param command_name string ----@param options table ----@param callback function -function Command.add(command_name, options, callback) - local description = options.description or '[Undocumented command]' - local arguments = options.arguments or {} - local default_values = options.default_values or {} - local required_rank = options.required_rank or Ranks.guest - local donator_only = options.donator_only or false - local debug_only = options.debug_only or false - local cheat_only = options.cheat_only or false - local capture_excess_arguments = options.capture_excess_arguments or false - local custom_help_text = options.custom_help_text or false - local allowed_by_server = options.allowed_by_server or false - local allowed_by_player = options.allowed_by_player - local log_command = options.log_command or (required_rank >= Ranks.admin) or false - local argument_list_size = table_size(arguments) - local argument_list = '' - - assert_existing_options(command_name, options) - - if nil == options.allowed_by_player then - allowed_by_player = true - end - - if (not _DEBUG and debug_only) and (not _CHEATS and cheat_only) then - return - end - - if not allowed_by_player and not allowed_by_server then - error(format("The command '%s' is not allowed by the server nor player, please enable at least one of them.", command_name)) - end - - for index, argument_name in pairs(arguments) do - local argument_display = argument_name - for default_value_name, _ in pairs(default_values) do - if default_value_name == argument_name then - argument_display = argument_display .. ':optional' - break - end - end - - if argument_list_size == index and capture_excess_arguments then - argument_display = argument_display .. ':sentence' - end - - argument_list = format('%s<%s> ', argument_list, argument_display) - end - - local extra = '' - - if allowed_by_server and not allowed_by_player then - extra = ' (Server only)' - elseif allowed_by_player and (required_rank > Ranks.guest) then - extra = {'command.required_rank', get_rank_name(required_rank)} - elseif allowed_by_player and donator_only then - extra = ' (Donator only)' - end - - local help_text = {'command.help_text_format',(custom_help_text or argument_list), description, extra} - - commands.add_command(command_name, help_text, function (command) - local print -- custom print reference in case no player is present - local player = game.player - local player_name = player and player.valid and player.name or '' - if not player or not player.valid then - print = log - - if not allowed_by_server then - print(format("The command '%s' is not allowed to be executed by the server.", command_name)) - return - end - else - print = player.print - - if not allowed_by_player then - print(format("The command '%s' is not allowed to be executed by players.", command_name)) - return - end - - if Rank.less_than(player_name, required_rank) then - print({'command.higher_rank_needed', command_name, get_rank_name(required_rank)}) - return - end - - if donator_only and not Donator.is_donator(player_name) then - print(format("The command '%s' is only allowed for donators.", command_name)) - return - end - end - - local named_arguments = {} - local from_command = {} - local raw_parameter_index = 1 - for param in gmatch(command.parameter or '', '%S+') do - if capture_excess_arguments and raw_parameter_index == argument_list_size then - if not from_command[raw_parameter_index] then - from_command[raw_parameter_index] = param - else - from_command[raw_parameter_index] = from_command[raw_parameter_index] .. ' ' .. param - end - else - from_command[raw_parameter_index] = param - raw_parameter_index = raw_parameter_index + 1 - end - end - - local errors = {} - - for index, argument in pairs(arguments) do - local parameter = from_command[index] - - if not parameter then - for default_value_name, default_value in pairs(default_values) do - if default_value_name == argument then - parameter = default_value - break - end - end - end - - if parameter == nil then - insert(errors, format('Argument "%s" from command %s is missing.', argument, command_name)) - else - named_arguments[argument] = parameter - end - end - - local return_early = false - - for _, error in pairs(errors) do - return_early = true - print(error) - end - - if return_early then - return - end - - if log_command then - local tick = 'pre-game' - if game then - tick = Utils.format_time(game.tick) - end - local server_time = Server.get_current_time() - if server_time then - server_time = format('(Server time: %s)', Timestamp.to_string(server_time)) - else - server_time = '' - end - - log(format('%s(Map time: %s) [%s Command] %s, used: %s %s', server_time, tick, (options.required_rank >= Ranks.admin) and 'Admin' or 'Player', player_name, command_name, serialize(named_arguments))) - end - - local success, error = pcall(function () - callback(named_arguments, player, command.tick) - end) - - if not success then - local serialized_arguments = serialize(named_arguments) - if _DEBUG then - print(format("%s triggered an error running a command and has been logged: '%s' with arguments %s", player_name, command_name, serialized_arguments)) - print(error) - return - end - - print(format('There was an error running %s, it has been logged.', command_name)) - log(format("Error while running '%s' with arguments %s: %s", command_name, serialized_arguments, error)) - end - end) -end - -function Command.search(keyword) - local matches = {} - local count = 0 - keyword = keyword:lower() - for name, description in pairs(commands.commands) do - local command = format('%s %s', name, description) - if match(command:lower(), keyword) then - count = count + 1 - matches[count] = command - end - end - - -- built-in commands use LocalisedString, which cannot be translated until player.print is called - for name in pairs(commands.game_commands) do - name = name - if match(name:lower(), keyword) then - count = count + 1 - matches[count] = name - end - end - - return matches -end - ---- Trigger messages on deprecated or defined commands, ignores the server -local function on_command(event) - if not event.player_index then - return - end - - local alternative = deprecated_command_alternatives[event.command] - if alternative then - local player = Game.get_player_by_index(event.player_index) - if player then - player.print(format('Warning! Usage of the command "/%s" is deprecated. Please use "/%s" instead.', event.command, alternative)) - end - end - - local notification = notify_on_commands[event.command] - if notification and event.player_index then - local player = Game.get_player_by_index(event.player_index) - if player then - player.print(notification) - end - end -end - ---- Traps command errors if not in DEBUG. -if not _DEBUG then - local old_add_command = commands.add_command - commands.add_command = - function(name, desc, func) - old_add_command( - name, - desc, - function(cmd) - local success, error = pcall(func, cmd) - if not success then - log(error) - Game.player_print('Sorry there was an error running ' .. cmd.name) - end - end - ) - end -end - -Event.add(defines.events.on_console_command, on_command) - -return Command diff --git a/utils/core.lua b/utils/core.lua deleted file mode 100644 index 744265b7..00000000 --- a/utils/core.lua +++ /dev/null @@ -1,223 +0,0 @@ ---- This file contains core utilities used by the redmew scenario. - --- Dependencies -local Game = require 'utils.game' --- @dep utils.game -local Color = require 'resources.color_presets' --- @dep resources.color_presets - --- localized functions -local random = math.random -local sqrt = math.sqrt -local floor = math.floor -local match = string.match -local insert = table.insert -local concat = table.concat - --- local constants -local prefix = '## - ' -local minutes_to_ticks = 60 * 60 -local hours_to_ticks = 60 * 60 * 60 -local ticks_to_minutes = 1 / minutes_to_ticks -local ticks_to_hours = 1 / hours_to_ticks - --- local variables -local Module = {} - ---- Measures distance between pos1 and pos2 -function Module.distance(pos1, pos2) - local dx = pos2.x - pos1.x - local dy = pos2.y - pos1.y - return sqrt(dx * dx + dy * dy) -end - ---- Takes msg and prints it to all players except provided player --- @param msg table if locale is used --- @param player the player not to send the message to --- @param color
    the color to use for the message, defaults to white -function Module.print_except(msg, player, color) - if not color then - color = Color.white - end - - for _, p in pairs(game.connected_players) do - if p ~= player then - p.print(msg, color) - end - end -end - ---- Prints a message to all online admins --- @param msg table if locale is used --- @param source string must be the name of a player, nil for server. -function Module.print_admins(msg, source) - local source_name - local chat_color - if source then - if type(source) == 'string' then - source_name = source - chat_color = game.players[source].chat_color - else - source_name = source.name - chat_color = source.chat_color - end - else - source_name = 'Server' - chat_color = Color.yellow - end - local formatted_msg = {'utils_core.print_admins',prefix, source_name, msg} - log(formatted_msg) - for _, p in pairs(game.connected_players) do - if p.admin then - p.print(formatted_msg, chat_color) - end - end -end - ---- Returns a valid string with the name of the actor of a command. -function Module.get_actor() - if game.player then - return game.player.name - end - return '' -end - -function Module.cast_bool(var) - if var then - return true - else - return false - end -end - -function Module.find_entities_by_last_user(player, surface, filters) - if type(player) == 'string' or not player then - error("bad argument #1 to '" .. debug.getinfo(1, 'n').name .. "' (number or LuaPlayer expected, got " .. type(player) .. ')', 1) - return - end - if type(surface) ~= 'table' and type(surface) ~= 'number' then - error("bad argument #2 to '" .. debug.getinfo(1, 'n').name .. "' (number or LuaSurface expected, got " .. type(surface) .. ')', 1) - return - end - local entities = {} - local filter = filters or {} - if type(surface) == 'number' then - surface = game.surfaces[surface] - end - if type(player) == 'number' then - player = Game.get_player_by_index(player) - end - filter.force = player.force.name - for _, e in pairs(surface.find_entities_filtered(filter)) do - if e.last_user == player then - insert(entities, e) - end - end - return entities -end - -function Module.ternary(c, t, f) - if c then - return t - else - return f - end -end - ---- Takes a time in ticks and returns a string with the time in format "x hour(s) x minute(s)" -function Module.format_time(ticks) - local result = {} - - local hours = floor(ticks * ticks_to_hours) - if hours > 0 then - ticks = ticks - hours * hours_to_ticks - insert(result, hours) - if hours == 1 then - insert(result, 'hour') - else - insert(result, 'hours') - end - end - - local minutes = floor(ticks * ticks_to_minutes) - insert(result, minutes) - if minutes == 1 then - insert(result, 'minute') - else - insert(result, 'minutes') - end - - return concat(result, ' ') -end - ---- Prints a message letting the player know they cannot run a command --- @param name string name of the command -function Module.cant_run(name) - Game.player_print("Can't run command (" .. name .. ') - insufficient permission.') -end - ---- Logs the use of a command and its user --- @param actor string with the actor's name (usually acquired by calling get_actor) --- @param command the command's name as table element --- @param parameters the command's parameters as a table (optional) -function Module.log_command(actor, command, parameters) - local action = concat {'[Admin-Command] ', actor, ' used: ', command} - if parameters then - action = concat {action, ' ', parameters} - end - log(action) -end - -function Module.comma_value(n) -- credit http://richard.warburton.it - local left, num, right = match(n, '^([^%d]*%d)(%d*)(.-)$') - return left .. (num:reverse():gsub('(%d%d%d)', '%1,'):reverse()) .. right -end - ---- Asserts the argument is one of type arg_types --- @param arg the variable to check --- @param arg_types the type as a table of sings --- @return boolean -function Module.verify_mult_types(arg, arg_types) - for _, arg_type in pairs(arg_types) do - if type(arg) == arg_type then - return true - end - end - return false -end - ---- Returns a random RGB color as a table -function Module.random_RGB() - return {r = random(0, 255), g = random(0, 255), b = random(0, 255)} -end - ---- Sets a table element to value while also returning value. --- @param tbl table to change the element of --- @param key string --- @param value nil|boolean|number|string|table to set the element to --- @return value -function Module.set_and_return(tbl, key, value) - tbl[key] = value - return value -end - --- add utility functions that exist in base factorio/util -require 'util' - ---- Moves a position according to the parameters given --- Notice: only accepts cardinal directions as direction --- @param position
    table containing a map position --- @param direction north, east, south, west --- @param distance --- @return
    modified position -Module.move_position = util.moveposition - ---- Takes a direction and gives you the opposite --- @param direction north, east, south, west, northeast, northwest, southeast, southwest --- @return representing the direction -Module.opposite_direction = util.oppositedirection - ---- Takes the string of a module and returns whether is it available or not --- @param name the name of the module (ex. 'utils.core') --- @return -Module.is_module_available = util.ismoduleavailable - -return Module diff --git a/utils/dump_env.lua b/utils/dump_env.lua deleted file mode 100644 index 97f92ff0..00000000 --- a/utils/dump_env.lua +++ /dev/null @@ -1,32 +0,0 @@ ---- A small debugging tool that writes the contents of _ENV to a file when the game loads. --- Useful for ensuring you get the same information when loading --- the reference and desync levels in desync reports. --- dependencies -local table = require 'utils.table' --- @dep utils.table -local Event = require 'utils.event' --- @dep utils.event - --- localized functions -local inspect = table.inspect - --- local constants -local filename = 'env_dump.lua' - --- Removes metatables and the package table -local filter = function(item, path) - if path[#path] ~= inspect.METATABLE and item ~= 'package' then - return item - end -end - -local function player_joined(event) - local dump_string = inspect(_ENV, {process = filter}) - if dump_string then - local s = string.format('tick on join: %s\n%s', event.tick, dump_string) - game.write_file(filename, s) - game.print('_ENV dumped into ' .. filename) - else - game.print('_ENV not dumped, dump_string was nil') - end -end - -Event.add(defines.events.on_player_joined_game, player_joined) diff --git a/utils/event.lua b/utils/event.lua index d4d3bd85..09673c5d 100644 --- a/utils/event.lua +++ b/utils/event.lua @@ -97,7 +97,7 @@ local EventCore = require 'utils.event_core' --- @dep utils.event_core local Global = require 'utils.global' --- @dep utils.global local Token = require 'utils.token' --- @dep utils.token -local Debug = require 'utils.debug' --- @dep utils.debug +local Debug = require 'overrides.debug' --- @dep overrides.debug local table_remove = table.remove local core_add = EventCore.add diff --git a/utils/game.lua b/utils/game.lua index 946d2420..c5ff5db2 100644 --- a/utils/game.lua +++ b/utils/game.lua @@ -1,5 +1,5 @@ local Global = require 'utils.global' --- @dep utils.global -local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Color = require 'utils.color_presets' --- @dep utils.color_presets local pairs = pairs local Game = {} diff --git a/utils/player_rewards.lua b/utils/player_rewards.lua deleted file mode 100644 index dec49ae7..00000000 --- a/utils/player_rewards.lua +++ /dev/null @@ -1,154 +0,0 @@ -local Global = require 'utils.global' --- @dep utils.global -local Game = require 'utils.game' --- @dep utils.game -local PlayerStats = require 'features.player_stats' --- @dep features.player_stats -local Command = require 'utils.command' --- @dep utils.command -local Ranks = require 'resources.ranks' --- @dep resources.ranks - -local format = string.format -local abs = math.abs -local concat = table.concat - -local Public = {} -local reward_token = {global.config.player_rewards.token} or {global.config.market.currency} or {'coin'} - -Global.register( - { - reward_token = reward_token - }, - function(tbl) - reward_token = tbl.reward_token - end -) - ---- Returns the single or plural form of the token name -local function get_token_plural(quantity) - if quantity and quantity > 1 then - return concat({reward_token[1], 's'}) - else - return reward_token[1] - end -end - ---- Set the item to use for rewards --- @param reward string - item name to use as reward --- @return boolean true - indicating success -Public.set_reward = function(reward) - if global.config.player_rewards.enabled == false then - return false - end - - reward_token[1] = reward - return true -end - ---- Returns the name of the reward item -Public.get_reward = function() - return reward_token[1] -end - ---- Gives reward tokens to the player --- @param player --- @param amount of reward tokens --- @param message an optional message to send to the affected player --- @return indicating how many were inserted or if operation failed -Public.give_reward = function(player, amount, message) - if global.config.player_rewards.enabled == false then - return 0 - end - - local player_index - if type(player) == 'number' then - player_index = player - player = Game.get_player_by_index(player) - else - player_index = player.index - end - local reward = {name = reward_token[1], count = amount} - if not player.can_insert(reward) then - return 0 - end - if message then - player.print(message) - end - local coin_difference = player.insert(reward) - if reward_token[1] == 'coin' then - PlayerStats.change_coin_earned(player_index, coin_difference) - end - return coin_difference -end - ---- Removes reward tokens from the player --- @param player --- @param amount of reward tokens --- @param message an optional message to send to the affected player --- @return indicating how many were removed or if operation failed -Public.remove_reward = function(player, amount, message) - if global.config.player_rewards.enabled == false then - return 0 - end - - local player_index - if type(player) == 'number' then - player_index = player - player = Game.get_player_by_index(player) - else - player_index = player.index - end - local unreward = {name = reward_token[1], count = amount} - if message then - player.print(message) - end - local coin_difference = player.remove_item(unreward) - if reward_token[1] == 'coin' then - PlayerStats.change_coin_earned(player_index, -coin_difference) - end - return coin_difference -end - -Command.add( - 'reward', - { - description = 'Gives a reward to a target player (removes if quantity is negative)', - arguments = {'target', 'quantity', 'reason'}, - default_values = {reason = false}, - required_rank = Ranks.admin, - capture_excess_arguments = true, - allowed_by_server = true, - allowed_by_player = true - }, - function(args, player) - local player_name = 'server' - if player then - player_name = player.name - end - - local target_name = args.target - local target = game.players[target_name] - if not target then - player.print('Target not found.') - return - end - - local quantity = tonumber(args.quantity) - if quantity > 0 then - Public.give_reward(target, quantity) - local string = format('%s has rewarded %s with %s %s', player_name, target_name, quantity, get_token_plural(quantity)) - if args.reason then - string = format('%s for %s', string, args.reason) - end - game.print(string) - elseif quantity < 0 then - quantity = abs(quantity) - Public.remove_reward(target, quantity) - local string = format('%s has punished %s by taking %s %s', player_name, target_name, quantity, get_token_plural(quantity)) - if args.reason then - string = format('%s for %s', string, args.reason) - end - game.print(string) - else - Game.player_print(" A reward of 0 is neither a reward nor a punishment, it's just dumb. Try harder.") - end - end -) - -return Public diff --git a/utils/recipe_locker.lua b/utils/recipe_locker.lua deleted file mode 100644 index 53d6c59c..00000000 --- a/utils/recipe_locker.lua +++ /dev/null @@ -1,58 +0,0 @@ ---- A module to prevent recipes from being unlocked by research. Accessed via the public functions. -local Event = require 'utils.event' --- @dep utils.event -local Global = require 'utils.global' --- @dep utils.global - -local Public = {} - -local recipes = {} - -Global.register( - { - recipes = recipes - }, - function(tbl) - recipes = tbl.recipes - end -) - -Event.add( - defines.events.on_research_finished, - function(event) - local p_force = game.forces.player - local r = event.research - for _, effect in pairs(r.effects) do - local recipe = effect.recipe - if recipe and recipes[recipe] then - p_force.recipes[recipe].enabled = false - end - end - end -) - -Event.on_init( - function() - for recipe in pairs(recipes) do - game.forces.player.recipes[recipe].enabled = false - end - end -) - ---- Locks recipes, preventing them from being enabled by research. --- Does not check if they should be enabled/disabled by existing research. --- @param tbl
    an array of recipe strings -function Public.lock_recipes(tbl) - for i = 1, #tbl do - recipes[tbl[i]] = true - end -end - ---- Unlocks recipes, allowing them to be enabled by research. --- Does not check if they should be enabled/disabled by existing research. --- @param tbl
    an array of recipe strings -function Public.unlock_recipes(tbl) - for i = 1, #tbl do - recipes[tbl[i]] = nil - end -end - -return Public diff --git a/utils/redmew_settings.lua b/utils/redmew_settings.lua deleted file mode 100644 index 2e4b0404..00000000 --- a/utils/redmew_settings.lua +++ /dev/null @@ -1,178 +0,0 @@ -local Global = require 'utils.global' --- @dep utils.global -local type = type -local error = error -local tonumber = tonumber -local tostring = tostring -local pairs = pairs -local format = string.format - ---- Contains a set of callable that will attempt to sanitize and transform the input -local settings_type = { - fraction = function (input) - input = tonumber(input) - - if input == nil then - return false, 'fraction setting type requires the input to be a valid number between 0 and 1.' - end - - if input < 0 then - input = 0 - end - - if input > 1 then - input = 1 - end - - return true, input - end, - string = function (input) - if input == nil then - return true, '' - end - - local input_type = type(input) - if input_type == 'string' then - return true, input - end - - if input_type == 'number' or input_type == 'boolean' then - return true, tostring(input) - end - - return false, 'string setting type requires the input to be either a valid string or something that can be converted to a string.' - end, - boolean = function (input) - local input_type = type(input) - - if input_type == 'boolean' then - return true, input - end - - if input_type == 'string' then - if input == '0' or input == '' or input == 'false' or input == 'no' then - return true, false - end - if input == '1' or input == 'true' or input == 'yes' then - return true, true - end - - return true, tonumber(input) ~= nil - end - - if input_type == 'number' then - return true, input ~= 0 - end - - return false, 'boolean setting type requires the input to be either a boolean, number or string that can be transformed to a boolean.' - end, -} - -local settings = {} -local memory = {} - -Global.register(memory, function (tbl) memory = tbl end) - -local Public = {} - -Public.types = {fraction = 'fraction', string = 'string', boolean = 'boolean'} - ----Register a specific setting with a sensitization setting type. ---- ---- Available setting types: ---- - fraction (number between 0 and 1) in either number or string form ---- - string a string or anything that can be cast to a string ---- - boolean, 1, 0, yes, no, true, false or an empty string for false ---- ---- This function must be called in the control stage, i.e. not inside an event. ---- ----@param name string ----@param setting_type string ----@param default mixed -function Public.register(name, setting_type, default) - if _LIFECYCLE ~= _STAGE.control then - error(format('You can only register setting names in the control stage, i.e. not inside events. Tried setting "%s" with type "%s".', name, setting_type), 2) - end - - if settings[name] then - error(format('Trying to register setting for "%s" while it has already been registered.', name), 2) - end - - local callback = settings_type[setting_type] - if not callback then - error(format('Trying to register setting for "%s" with type "%s" while this type does not exist.', name, setting_type), 2) - end - - local setting = { - default = default, - callback = callback, - } - - settings[name] = setting - - return setting -end - ----Sets a setting to a specific value for a player. ---- ----In order to get a setting value, it has to be registered via the "register" function. ---- ----@param player_index number ----@param name string ----@param value mixed -function Public.set(player_index, name, value) - local setting = settings[name] - if not setting then - return error(format('Setting "%s" does not exist.', name), 2) - end - - local success, sanitized_value = setting.callback(value) - - if not success then - error(format('Setting "%s" failed: %s', name, sanitized_value), 2) - end - - local player_settings = memory[player_index] - if not player_settings then - player_settings = {} - memory[player_index] = player_settings - end - - player_settings[name] = sanitized_value - - return sanitized_value -end - ----Returns the value of a setting for this player. ---- ----In order to set a setting value, it has to be registered via the "register" function. ---- ----@param player_index number ----@param name string -function Public.get(player_index, name) - local setting = settings[name] - if not setting then - return error(format('Setting "%s" does not exist.', name), 2) - end - - local player_settings = memory[player_index] - if not player_settings then - return setting.default - end - - local player_setting = player_settings[name] - return player_setting ~= nil and player_setting or setting.default -end - ----Returns a table of all settings for a given player in a key => value set-up ----@param player_index number -function Public.all(player_index) - local player_settings = memory[player_index] or {} - local output = {} - for name, data in pairs(settings) do - output[name] = player_settings[name] or data.default - end - - return output -end - -return Public diff --git a/utils/state_machine.lua b/utils/state_machine.lua deleted file mode 100644 index 9d298a52..00000000 --- a/utils/state_machine.lua +++ /dev/null @@ -1,119 +0,0 @@ ---- This module provides a classical mealy/moore state machine. --- Each machine in constructed by calling new() --- States and Transitions are lazily added to the machine as transition handlers and state tick handlers are registered. --- However the state machine must be fully defined after init is done. Dynamic machine changes are currently unsupported --- An example usage can be found here: map_gen\combined\tetris\control.lua - -local Module = {} - -local Debug = require 'utils.debug' --- @dep utils.debug - -local in_state_callbacks = {} -local transaction_callbacks = {} -local max_stack_depth = 20 -local machine_count = 0 -local control_stage = _STAGE.control - ---- Transitions the supplied machine into a given state and executes all transaction_callbacks --- @param self StateMachine --- @param new_state number/string The new state to transition to -function Module.transition(self, new_state) - Debug.print(string.format('Transitioning from state %d to state %d.', self.state, new_state)) - local old_state = self.state - - local stack_depth = self.stack_depth - self.stack_depth = stack_depth + 1 - if stack_depth > max_stack_depth then - if _DEBUG then - error('[WARNING] Stack overflow at:' .. debug.traceback()) - else - log('[WARNING] Stack overflow at:' .. debug.traceback()) - end - end - - local exit_callbacks = transaction_callbacks[self.id][old_state] - if exit_callbacks then - local entry_callbacks = exit_callbacks[new_state] - if entry_callbacks then - for i = 1, #entry_callbacks do - local callback = entry_callbacks[i] - if callback then - callback() - end - end - end - end - self.state = new_state -end - ---- Is this machine in this state? --- @param self StateMachine --- @param state number/string --- @return boolean -function Module.in_state(self, state) - return self.state == state -end - ---- Invoke a machine tick. Will execute all in_state_callbacks of the given machine --- @param self StateMachine the machine, whose handlers will be invoked -function Module.machine_tick(self) - local callbacks = in_state_callbacks[self.id][self.state] - if callbacks then - for i=1, #callbacks do - local callback = callbacks[i] - if callback then - callback() - end - end - end - self.stack_depth = 0 -end - ---- Register a handler that will be invoked by StateMachine.machine_tick --- You may register multiple handlers for the same transition --- NOTICE: This function will invoke an error if called after init. Dynamic machine changes are currently unsupported --- @param self StateMachine the machine --- @param state number/string The state, that the machine will be in, when callback is invoked --- @param callback function -function Module.register_state_tick_callback(self, state, callback) - if _LIFECYCLE ~= control_stage then - error('Calling StateMachine.register_state_tick_callback after the control stage is unsupported due to desyncs.', 2) - end - in_state_callbacks[self.id][state] = in_state_callbacks[self.id][state] or {} - table.insert(in_state_callbacks[self.id][state], callback) -end - ---- Register a handler that will be invoked by StateMachine.transition --- You may register multiple handlers for the same transition --- NOTICE: This function will invoke an error if called after init. Dynamic machine changes are currently unsupported --- @param self StateMachine the machine --- @param old number/string exiting state --- @param new number/string entering state --- @param callback function -function Module.register_transition_callback(self, old, new, callback) - if _LIFECYCLE ~= control_stage then - error('Calling StateMachine.register_transition_callback after the control stage is unsupported due to desyncs.', 2) - end - transaction_callbacks[self.id][old] = transaction_callbacks[self.id][old] or {} - transaction_callbacks[self.id][old][new] = transaction_callbacks[self.id][old][new] or {} - table.insert(transaction_callbacks[self.id][old][new], callback) -end - ---- Constructs a new state machine --- @param init_state number/string The starting state of the machine --- @return StateMachine The constructed state machine object -function Module.new(init_state) - if _LIFECYCLE ~= control_stage then - error('Calling StateMachine.new after the control stage is unsupported due to desyncs.', 2) - end - machine_count = machine_count + 1 - in_state_callbacks[machine_count] = {} - transaction_callbacks[machine_count] = {} - return { - state = init_state, - stack_depth = 0, - id = machine_count, - } -end - -return Module diff --git a/utils/timestamp.lua b/utils/timestamp.lua deleted file mode 100644 index 3c2eb73e..00000000 --- a/utils/timestamp.lua +++ /dev/null @@ -1,152 +0,0 @@ ---- source https://github.com/daurnimator/luatz/blob/master/luatz/timetable.lua --- edited down to just what is needed. - -local Public = {} - -local floor = math.floor -local strformat = string.format - -local function borrow(tens, units, base) - local frac = tens % 1 - units = units + frac * base - tens = tens - frac - return tens, units -end - -local function carry(tens, units, base) - if units >= base then - tens = tens + floor(units / base) - units = units % base - elseif units < 0 then - tens = tens + floor(units / base) - units = (base + units) % base - end - return tens, units -end - -local function is_leap(y) - if (y % 4) ~= 0 then - return false - elseif (y % 100) ~= 0 then - return true - else - return (y % 400) == 0 - end -end - -local mon_lengths = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} - --- Number of days in year until start of month; not corrected for leap years -local months_to_days_cumulative = {0} -for i = 2, 12 do - months_to_days_cumulative[i] = months_to_days_cumulative[i - 1] + mon_lengths[i - 1] -end - -local function month_length(m, y) - if m == 2 then - return is_leap(y) and 29 or 28 - else - return mon_lengths[m] - end -end - -local function day_of_year(day, month, year) - local y_day = months_to_days_cumulative[month] - if month > 2 and is_leap(year) then - y_day = y_day + 1 - end - return y_day + day -end - -local function leap_years_since(year) - return floor(year / 4) - floor(year / 100) + floor(year / 400) -end - -local leap_years_since_1970 = leap_years_since(1970) - -local function normalise(year, month, day, hour, min, sec) - -- `month` and `day` start from 1, need -1 and +1 so it works modulo - month, day = month - 1, day - 1 - - -- Convert everything (except seconds) to an integer - -- by propagating fractional components down. - year, month = borrow(year, month, 12) - -- Carry from month to year first, so we get month length correct in next line around leap years - year, month = carry(year, month, 12) - month, day = borrow(month, day, month_length(floor(month + 1), year)) - day, hour = borrow(day, hour, 24) - hour, min = borrow(hour, min, 60) - min, sec = borrow(min, sec, 60) - - -- Propagate out of range values up - -- e.g. if `min` is 70, `hour` increments by 1 and `min` becomes 10 - -- This has to happen for all columns after borrowing, as lower radix's may be pushed out of range - min, sec = carry(min, sec, 60) -- TODO: consider leap seconds? - hour, min = carry(hour, min, 60) - day, hour = carry(day, hour, 24) - -- Ensure `day` is not underflowed - -- Add a whole year of days at a time, this is later resolved by adding months - -- TODO[OPTIMIZE]: This could be slow if `day` is far out of range - while day < 0 do - month = month - 1 - if month < 0 then - year = year - 1 - month = 11 - end - day = day + month_length(month + 1, year) - end - year, month = carry(year, month, 12) - - -- TODO[OPTIMIZE]: This could potentially be slow if `day` is very large - while true do - local i = month_length(month + 1, year) - if day < i then - break - end - day = day - i - month = month + 1 - if month >= 12 then - month = 0 - year = year + 1 - end - end - - -- Now we can place `day` and `month` back in their normal ranges - -- e.g. month as 1-12 instead of 0-11 - month, day = month + 1, day + 1 - - return {year = year, month = month, day = day, hour = hour, min = min, sec = sec} -end - ---- Converts unix epoch timestamp into table {year: number, month: number, day: number, hour: number, min: number, sec: number} --- @param seconds unix epoch timestamp --- @return {year: number, month: number, day: number, hour: number, min: number, sec: number} -function Public.to_timetable(seconds) - return normalise(1970, 1, 1, 0, 0, seconds) -end - ---- Converts timetable into unix epoch timestamp --- @param timetable
    {year: number, month: number, day: number, hour: number, min: number, sec: number} --- @return number -function Public.from_timetable(timetable) - local tt = normalise(timetable.year, timetable.month, timetable.day, timetable.hour, timetable.min, timetable.sec) - - local year, month, day, hour, min, sec = tt.year, tt.month, tt.day, tt.hour, tt.min, tt.sec - - local days_since_epoch = - day_of_year(day, month, year) + 365 * (year - 1970) + -- Each leap year adds one day - (leap_years_since(year - 1) - leap_years_since_1970) - - 1 - - return days_since_epoch * (60 * 60 * 24) + hour * (60 * 60) + min * 60 + sec -end - ---- Converts unix epoch timestamp into human readable string. --- @param seconds unix epoch timestamp --- @return string -function Public.to_string(seconds) - local tt = normalise(1970, 1, 1, 0, 0, seconds) - return strformat('%04u-%02u-%02u %02u:%02u:%02d', tt.year, tt.month, tt.day, tt.hour, tt.min, tt.sec) -end - -return Public From 5dbc7a5e5c2023e6ef9db0b7f84eae50e2a93133 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 29 Mar 2020 23:14:05 +0100 Subject: [PATCH 64/81] Added some runtime checks to role --- expcore/common.lua | 18 ++++++++++++++++++ expcore/roles.lua | 8 +++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/expcore/common.lua b/expcore/common.lua index be47f8dd..fd87f65f 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -95,6 +95,24 @@ function Common.validate_argument_multi_type(value, test_types, param_name, para return true end +--- Will raise an error if called during runtime +-- @usage error_if_runtime() +function Common.error_if_runtime() + if _LIFECYCLE == 8 then + local function_name = debug.getinfo(2,'n').name or '' + error(function_name..' can not be called during runtime',3) + end +end + +--- Will raise an error if the function is a closure +-- @usage error_if_runetime_closure(func) +function Common.error_if_runetime_closure(func) + if _LIFECYCLE == 8 and Debug.is_closure(func) then + local function_name = debug.getinfo(2,'n').name or '' + error(function_name..' can not be called during runtime with a closure',3) + end +end + --- Value Returns. -- @section valueReturns diff --git a/expcore/roles.lua b/expcore/roles.lua index 11616822..aefa06a7 100644 --- a/expcore/roles.lua +++ b/expcore/roles.lua @@ -127,7 +127,7 @@ local Roles = { roles={}, -- Contains the raw info for the roles, indexed by role name flags={}, -- Contains functions that run when a flag is added/removed from a player internal={}, -- Contains all internally accessed roles, such as root, default - players={} + players={} -- Contains the roles that players have }, events = { on_role_assigned=script.generate_event_name(), @@ -425,6 +425,7 @@ end -- @tparam table order table a which is keyed only by numbers (start 1) and values are roles in order with highest first function Roles.define_role_order(order) -- Clears and then rebuilds the order table + _C.error_if_runtime() Roles.config.order = {} local done = {} for _,role in ipairs(order) do @@ -462,6 +463,7 @@ end -- flag param - player - the player that has had they roles changed -- flag param - state - the state of the flag, aka if the flag is present function Roles.define_flag_trigger(name,callback) + _C.error_if_runtime() Roles.config.flags[name] = Async.register(callback) end @@ -487,6 +489,7 @@ end -- @tparam[opt=name] string short_hand the shortened version of the name -- @treturn Roles._prototype the start of the config chain for this role function Roles.new_role(name,short_hand) + _C.error_if_runtime() if Roles.config.roles[name] then return error('Role name is non unique') end local role = setmetatable({ name=name, @@ -602,6 +605,7 @@ end -- @tparam[opt=false] boolean use_factorio_api when true the custom permission group module is ignored -- @treturn Roles._prototype allows chaining function Roles._prototype:set_permission_group(name,use_factorio_api) + _C.error_if_runtime() if use_factorio_api then self.permission_group = {true,name} else @@ -617,6 +621,7 @@ end -- @tparam string role the name of the role that will be the parent; has imminent effect if role is already defined -- @treturn Roles._prototype allows chaining function Roles._prototype:set_parent(role) + _C.error_if_runtime() self.parent = role role = Roles.get_role_from_any(role) if not role then return self end @@ -629,6 +634,7 @@ end -- @tparam function callback receives only one param which is player to promote, return true to promote the player -- @treturn Roles._prototype allows chaining function Roles._prototype:set_auto_promote_condition(callback) + _C.error_if_runetime_closure(callback) self.auto_promote_condition = callback return self end From 95af6cfc34a03c44688e6f634bb04fc3e31b019b Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 29 Mar 2020 23:39:24 +0100 Subject: [PATCH 65/81] Cleaned Config --- config/_file_loader.lua | 10 +++++----- config/chat_reply.lua | 2 +- .../command_auth_admin.lua} | 0 .../command_auth_roles.lua} | 0 .../command_general_parse.lua} | 0 .../command_role_parse.lua} | 4 ++-- .../command_runtime_disable.lua} | 0 config/{ => expcore}/permission_groups.lua | 0 config/{ => expcore}/roles.lua | 14 -------------- .../player_list_actions.lua} | 2 +- config/{ => gui}/rockets.lua | 0 config/{ => gui}/science.lua | 0 config/{ => gui}/tasks.lua | 0 config/{ => gui}/warps.lua | 0 expcore/commands.lua | 2 +- expcore/common.lua | 13 ------------- expcore/roles.lua | 2 +- modules/addons/death-logger.lua | 2 +- modules/addons/discord-alerts.lua | 2 +- modules/addons/scorched-earth.lua | 2 +- modules/commands/admin-chat.lua | 4 ++-- modules/commands/bonus.lua | 2 +- modules/commands/cheat-mode.lua | 2 +- modules/commands/clear-inventory.lua | 4 ++-- modules/commands/find.lua | 2 +- modules/commands/help.lua | 2 +- modules/commands/home.lua | 2 +- modules/commands/jail.lua | 4 ++-- modules/commands/kill.lua | 4 ++-- modules/commands/rainbow.lua | 2 +- modules/commands/repair.lua | 2 +- modules/commands/reports.lua | 4 ++-- modules/commands/roles.lua | 5 +---- modules/commands/tag.lua | 4 ++-- modules/commands/teleport.lua | 2 +- modules/commands/warnings.lua | 4 ++-- modules/control/jail.lua | 2 +- modules/control/production.lua | 2 +- modules/control/rockets.lua | 2 +- modules/control/warps.lua | 2 +- modules/gui/player-list.lua | 4 ++-- modules/gui/rocket-info.lua | 4 ++-- modules/gui/science-info.lua | 4 ++-- modules/gui/task-list.lua | 2 +- modules/gui/warp-list.lua | 2 +- 45 files changed, 49 insertions(+), 79 deletions(-) rename config/{expcore-commands/auth_admin.lua => expcore/command_auth_admin.lua} (100%) rename config/{expcore-commands/auth_roles.lua => expcore/command_auth_roles.lua} (100%) rename config/{expcore-commands/parse_general.lua => expcore/command_general_parse.lua} (100%) rename config/{expcore-commands/parse_roles.lua => expcore/command_role_parse.lua} (92%) rename config/{expcore-commands/auth_runtime_disable.lua => expcore/command_runtime_disable.lua} (100%) rename config/{ => expcore}/permission_groups.lua (100%) rename config/{ => expcore}/roles.lua (95%) rename config/{action_buttons.lua => gui/player_list_actions.lua} (98%) rename config/{ => gui}/rockets.lua (100%) rename config/{ => gui}/science.lua (100%) rename config/{ => gui}/tasks.lua (100%) rename config/{ => gui}/warps.lua (100%) diff --git a/config/_file_loader.lua b/config/_file_loader.lua index 452be0a1..c78f6bde 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -52,9 +52,9 @@ return { 'modules.gui.server-ups', 'modules.commands.debug', -- Config Files - 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins - 'config.expcore-commands.auth_roles', -- commands must be allowed via the role config - 'config.expcore-commands.auth_runtime_disable', -- allows commands to be enabled and disabled during runtime - 'config.permission_groups', -- loads some predefined permission groups - 'config.roles', -- loads some predefined roles + 'config.expcore.command_auth_admin', -- commands tagged with admin_only are blocked for non admins + 'config.expcore.command_auth_roles', -- commands must be allowed via the role config + 'config.expcore.command_runtime_disable', -- allows commands to be enabled and disabled during runtime + 'config.expcore.permission_groups', -- loads some predefined permission groups + 'config.expcore.roles', -- loads some predefined roles } \ No newline at end of file diff --git a/config/chat_reply.lua b/config/chat_reply.lua index 52eb80be..d4b66a16 100644 --- a/config/chat_reply.lua +++ b/config/chat_reply.lua @@ -2,7 +2,7 @@ -- @config Chat-Reply local Async = require 'expcore.async' -local format_time = _C.ext_require('expcore.common','format_time') --- @dep expcore.common +local format_time = _C.format_time --- @dep expcore.common local async_message = Async.register(function(player, message) player.print(message) diff --git a/config/expcore-commands/auth_admin.lua b/config/expcore/command_auth_admin.lua similarity index 100% rename from config/expcore-commands/auth_admin.lua rename to config/expcore/command_auth_admin.lua diff --git a/config/expcore-commands/auth_roles.lua b/config/expcore/command_auth_roles.lua similarity index 100% rename from config/expcore-commands/auth_roles.lua rename to config/expcore/command_auth_roles.lua diff --git a/config/expcore-commands/parse_general.lua b/config/expcore/command_general_parse.lua similarity index 100% rename from config/expcore-commands/parse_general.lua rename to config/expcore/command_general_parse.lua diff --git a/config/expcore-commands/parse_roles.lua b/config/expcore/command_role_parse.lua similarity index 92% rename from config/expcore-commands/parse_roles.lua rename to config/expcore/command_role_parse.lua index f6923404..12e76bbc 100644 --- a/config/expcore-commands/parse_roles.lua +++ b/config/expcore/command_role_parse.lua @@ -9,8 +9,8 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Roles = require 'expcore.roles' --- @dep expcore.roles -local auto_complete = _C.ext_require('expcore.common','auto_complete') --- @dep expcore.common -require 'config.expcore-commands.parse_general' +local auto_complete = _C.auto_complete --- @dep expcore.common +require 'config.expcore.command_general_parse' Commands.add_parse('role',function(input,player,reject) if not input then return end diff --git a/config/expcore-commands/auth_runtime_disable.lua b/config/expcore/command_runtime_disable.lua similarity index 100% rename from config/expcore-commands/auth_runtime_disable.lua rename to config/expcore/command_runtime_disable.lua diff --git a/config/permission_groups.lua b/config/expcore/permission_groups.lua similarity index 100% rename from config/permission_groups.lua rename to config/expcore/permission_groups.lua diff --git a/config/roles.lua b/config/expcore/roles.lua similarity index 95% rename from config/roles.lua rename to config/expcore/roles.lua index 943e3709..ef3e1c51 100644 --- a/config/roles.lua +++ b/config/expcore/roles.lua @@ -3,20 +3,6 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles --- Use these to adjust for ticks ie game.tick < 5*minutes -local seconds, minutes, hours = 60, 3600, 216000 - ---[[ - -- cant use a factory as it has up values ;-; - local function playtime(time_required) - return function(player) - if player.online_time > time_required then - return true - end - end - end -]] - --- Role flags that will run when a player changes roles Roles.define_flag_trigger('is_admin',function(player,state) player.admin = state diff --git a/config/action_buttons.lua b/config/gui/player_list_actions.lua similarity index 98% rename from config/action_buttons.lua rename to config/gui/player_list_actions.lua index 77ad6b9d..1bd19bbf 100644 --- a/config/action_buttons.lua +++ b/config/gui/player_list_actions.lua @@ -13,7 +13,7 @@ local Reports = require 'modules.control.reports' --- @dep modules.control.repor local Warnings = require 'modules.control.warnings' --- @dep modules.control.warnings local Jail = require 'modules.control.jail' --- @dep modules.control.jail local Colors = require 'utils.color_presets' --- @dep utils.color_presets -local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common +local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common local selected_player_store = '' local selected_action_store = '' diff --git a/config/rockets.lua b/config/gui/rockets.lua similarity index 100% rename from config/rockets.lua rename to config/gui/rockets.lua diff --git a/config/science.lua b/config/gui/science.lua similarity index 100% rename from config/science.lua rename to config/gui/science.lua diff --git a/config/tasks.lua b/config/gui/tasks.lua similarity index 100% rename from config/tasks.lua rename to config/gui/tasks.lua diff --git a/config/warps.lua b/config/gui/warps.lua similarity index 100% rename from config/warps.lua rename to config/gui/warps.lua diff --git a/expcore/commands.lua b/expcore/commands.lua index a64370ef..b84adea4 100644 --- a/expcore/commands.lua +++ b/expcore/commands.lua @@ -196,7 +196,7 @@ ]] local Game = require 'utils.game' --- @dep utils.game -local player_return,write_json = _C.ext_require('expcore.common','player_return','write_json') --- @dep expcore.common +local player_return,write_json = _C.player_return, _C.write_json --- @dep expcore.common local Commands = { defines={ -- common values are stored error like signals diff --git a/expcore/common.lua b/expcore/common.lua index fd87f65f..983cae4d 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -192,19 +192,6 @@ function Common.opt_require(path) else return nil,rtn end end ---- Calls a require and returns only the keys given, file must return a table --- @usage local extract, param_check = _C.ext_require('expcore.common','extract','param_check') --- @dep expcore.common --- @tparam string path the path that you want to require --- @tparam string ... the name of the keys that you want returned --- @return the keys in the order given -function Common.ext_require(path,...) - local rtn = require(path) - if type(rtn) ~= 'table' then - error('File did not return a table, can not extract keys.',2) - end - return table.extract_keys(rtn,...) -end - --- Returns a desync safe file path for the current file -- @tparam[opt=0] number offset the offset in the stack to get, 0 is current file -- @treturn string the file path diff --git a/expcore/roles.lua b/expcore/roles.lua index aefa06a7..8c245ec8 100644 --- a/expcore/roles.lua +++ b/expcore/roles.lua @@ -118,7 +118,7 @@ local Event = require 'utils.event' --- @dep utils.event local Groups = require 'expcore.permission_groups' --- @dep expcore.permission_groups local Async = require 'expcore.async' --- @dep expcore.async local Colours = require 'utils.color_presets' --- @dep utils.color_presets -local write_json = _C.ext_require('expcore.common','write_json') --- @dep expcore.common +local write_json = _C.write_json --- @dep expcore.common local Roles = { _prototype={}, diff --git a/modules/addons/death-logger.lua b/modules/addons/death-logger.lua index 6f4be5d7..2e6d90d0 100644 --- a/modules/addons/death-logger.lua +++ b/modules/addons/death-logger.lua @@ -5,7 +5,7 @@ local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global local config = require 'config.death_logger' --- @dep config.death_logger -local format_time,move_items = _C.ext_require('expcore.common','format_time','move_items') --- @dep expcore.common +local format_time,move_items = _C.format_time, _C.move_items --- @dep expcore.common local deaths = { archive={} -- deaths moved here after body is gone diff --git a/modules/addons/discord-alerts.lua b/modules/addons/discord-alerts.lua index 22bba566..f50271aa 100644 --- a/modules/addons/discord-alerts.lua +++ b/modules/addons/discord-alerts.lua @@ -4,7 +4,7 @@ local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game local Colors = require 'utils.color_presets' --- @dep utils.color_presets -local write_json,format_time = _C.ext_require('expcore.common','write_json','format_time') --- @dep expcore.common +local write_json,format_time = _C.write_json, _C.format_time --- @dep expcore.common local config = require 'config.discord_alerts' --- @dep config.discord_alerts local function get_player_name(event) diff --git a/modules/addons/scorched-earth.lua b/modules/addons/scorched-earth.lua index 9ae946f5..c6c822c5 100644 --- a/modules/addons/scorched-earth.lua +++ b/modules/addons/scorched-earth.lua @@ -4,7 +4,7 @@ local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global -local print_grid_value, clear_flying_text = _C.ext_require('expcore.common','print_grid_value','clear_flying_text') --- @dep expcore.common +local print_grid_value, clear_flying_text = _C.print_grid_value, _C.clear_flying_text --- @dep expcore.common local config = require 'config.scorched_earth' --- @dep config.scorched_earth -- Loops over the config and finds the wile which has the highest value for strength diff --git a/modules/commands/admin-chat.lua b/modules/commands/admin-chat.lua index 9a8182cb..faf239f7 100644 --- a/modules/commands/admin-chat.lua +++ b/modules/commands/admin-chat.lua @@ -4,8 +4,8 @@ ]] local Commands = require 'expcore.commands' --- @dep expcore.commands -local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common -require 'config.expcore-commands.parse_general' +local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +require 'config.expcore.command_general_parse' --- Sends a message in chat that only admins can see -- @command admin-chat diff --git a/modules/commands/bonus.lua b/modules/commands/bonus.lua index 2a63c6d5..b39fc1f1 100644 --- a/modules/commands/bonus.lua +++ b/modules/commands/bonus.lua @@ -9,7 +9,7 @@ local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game local Store = require 'expcore.store' --- @dep expcore.store local config = require 'config.bonuses' --- @dep config.bonuses -require 'config.expcore-commands.parse_general' +require 'config.expcore.command_general_parse' -- Store bonus percentages keyed by player name local bonus_store = Store.register(function(player) diff --git a/modules/commands/cheat-mode.lua b/modules/commands/cheat-mode.lua index caef97c9..f3f525df 100644 --- a/modules/commands/cheat-mode.lua +++ b/modules/commands/cheat-mode.lua @@ -4,7 +4,7 @@ ]] local Commands = require 'expcore.commands' --- @dep expcore.commands -require 'config.expcore-commands.parse_general' +require 'config.expcore.command_general_parse' --- Toggles cheat mode for your player, or another player. -- @command toggle-cheat-mode diff --git a/modules/commands/clear-inventory.lua b/modules/commands/clear-inventory.lua index 91e6c7e5..e684fb5e 100644 --- a/modules/commands/clear-inventory.lua +++ b/modules/commands/clear-inventory.lua @@ -4,8 +4,8 @@ ]] local Commands = require 'expcore.commands' --- @dep expcore.commands -local move_items = _C.ext_require('expcore.common','move_items') --- @dep expcore.common -require 'config.expcore-commands.parse_roles' +local move_items = _C.move_items --- @dep expcore.common +require 'config.expcore.command_role_parse' --- Clears a players inventory -- @command clear-inventory diff --git a/modules/commands/find.lua b/modules/commands/find.lua index f2770ab6..58ab5530 100644 --- a/modules/commands/find.lua +++ b/modules/commands/find.lua @@ -4,7 +4,7 @@ ]] local Commands = require 'expcore.commands' --- @dep expcore.commands -require 'config.expcore-commands.parse_general' +require 'config.expcore.command_general_parse' --- Find a player on your map. -- @command find-on-map diff --git a/modules/commands/help.lua b/modules/commands/help.lua index 62dac168..af43910d 100644 --- a/modules/commands/help.lua +++ b/modules/commands/help.lua @@ -5,7 +5,7 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Global = require 'utils.global' --- @dep utils.global -require 'config.expcore-commands.parse_general' +require 'config.expcore.command_general_parse' local results_per_page = 5 diff --git a/modules/commands/home.lua b/modules/commands/home.lua index 0d0dd92a..c6ce9078 100644 --- a/modules/commands/home.lua +++ b/modules/commands/home.lua @@ -5,7 +5,7 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Global = require 'utils.global' --- @dep utils.global -require 'config.expcore-commands.parse_general' +require 'config.expcore.command_general_parse' local homes = {} Global.register(homes,function(tbl) diff --git a/modules/commands/jail.lua b/modules/commands/jail.lua index 279eb373..cea441d8 100644 --- a/modules/commands/jail.lua +++ b/modules/commands/jail.lua @@ -5,8 +5,8 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Jail = require 'modules.control.jail' --- @dep modules.control.jail -local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common -require 'config.expcore-commands.parse_roles' +local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common +require 'config.expcore.command_role_parse' --- Puts a player into jail and removes all other roles. -- @command jail diff --git a/modules/commands/kill.lua b/modules/commands/kill.lua index 2396be52..3fea3e9a 100644 --- a/modules/commands/kill.lua +++ b/modules/commands/kill.lua @@ -5,8 +5,8 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Roles = require 'expcore.roles' --- @dep expcore.roles -require 'config.expcore-commands.parse_general' -require 'config.expcore-commands.parse_roles' +require 'config.expcore.command_general_parse' +require 'config.expcore.command_role_parse' --- Kills yourself or another player. -- @command kill diff --git a/modules/commands/rainbow.lua b/modules/commands/rainbow.lua index 4a29fe6a..350e0ae6 100644 --- a/modules/commands/rainbow.lua +++ b/modules/commands/rainbow.lua @@ -4,7 +4,7 @@ ]] local Commands = require 'expcore.commands' --- @dep expcore.commands -local format_chat_colour = _C.ext_require('expcore.common','format_chat_colour') --- @dep expcore.common +local format_chat_colour = _C.format_chat_colour --- @dep expcore.common local function step_component(c1,c2) if c1 < 0 then diff --git a/modules/commands/repair.lua b/modules/commands/repair.lua index cd7d67d6..f7ff434c 100644 --- a/modules/commands/repair.lua +++ b/modules/commands/repair.lua @@ -5,7 +5,7 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local config = require 'config.repair' --- @dep config.repair -require 'config.expcore-commands.parse_general' +require 'config.expcore.command_general_parse' local max_time_to_live = 4294967295 -- unit32 max --- Repairs entities on your force around you diff --git a/modules/commands/reports.lua b/modules/commands/reports.lua index 51f2f493..93ab6008 100644 --- a/modules/commands/reports.lua +++ b/modules/commands/reports.lua @@ -6,8 +6,8 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles local Commands = require 'expcore.commands' --- @dep expcore.commands local Reports = require 'modules.control.reports' --- @dep modules.control.reports -local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common -require 'config.expcore-commands.parse_general' +local format_chat_player_name = _C.format_chat_player_name--- @dep expcore.common +require 'config.expcore.command_general_parse' --- Reports a player and notifies moderators -- @command report diff --git a/modules/commands/roles.lua b/modules/commands/roles.lua index 448109f0..af36302a 100644 --- a/modules/commands/roles.lua +++ b/modules/commands/roles.lua @@ -6,10 +6,7 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Roles = require 'expcore.roles' --- @dep expcore.roles local Colours = require 'utils.color_presets' --- @dep utils.color_presets -local format_chat_player_name, format_chat_colour_localized = _C.ext_require('expcore.common', - 'format_chat_player_name', - 'format_chat_colour_localized' -) +local format_chat_player_name, format_chat_colour_localized = _C.format_chat_player_name, _C.format_chat_colour_localized --- Assigns a role to a player -- @command assign-role diff --git a/modules/commands/tag.lua b/modules/commands/tag.lua index e8c51e9b..a0400cf2 100644 --- a/modules/commands/tag.lua +++ b/modules/commands/tag.lua @@ -5,8 +5,8 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Roles = require 'expcore.roles' --- @dep expcore.roles -require 'config.expcore-commands.parse_general' -require 'config.expcore-commands.parse_roles' +require 'config.expcore.command_general_parse' +require 'config.expcore.command_role_parse' --- Sets your player tag. -- @command tag diff --git a/modules/commands/teleport.lua b/modules/commands/teleport.lua index 2117f18d..f5e88906 100644 --- a/modules/commands/teleport.lua +++ b/modules/commands/teleport.lua @@ -4,7 +4,7 @@ ]] local Commands = require 'expcore.commands' --- @dep expcore.commands -require 'config.expcore-commands.parse_general' +require 'config.expcore.command_general_parse' local function teleport(from_player,to_player) local surface = to_player.surface diff --git a/modules/commands/warnings.lua b/modules/commands/warnings.lua index 9c1dfcef..42f7b868 100644 --- a/modules/commands/warnings.lua +++ b/modules/commands/warnings.lua @@ -5,9 +5,9 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local Warnings = require 'modules.control.warnings' --- @dep modules.control.warnings -local format_chat_player_name = _C.ext_require('expcore.common','format_chat_player_name') --- @dep expcore.common +local format_chat_player_name = _C.format_chat_player_name --- @dep expcore.common local config = require 'config.warnings' --- @dep config.warnings -require 'config.expcore-commands.parse_roles' +require 'config.expcore.command_role_parse' --- Gives a warning to a player; may lead to automatic script action. -- @command give-warning diff --git a/modules/control/jail.lua b/modules/control/jail.lua index 10a387a1..e0cfe837 100644 --- a/modules/control/jail.lua +++ b/modules/control/jail.lua @@ -23,7 +23,7 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global -local move_items = _C.ext_require('expcore.common','move_items') --- @dep expcore.common +local move_items = _C.move_items --- @dep expcore.common local valid_player = Game.get_player_from_any local assign_roles = Roles.assign_player diff --git a/modules/control/production.lua b/modules/control/production.lua index 16eb97b9..f6e6c1c2 100644 --- a/modules/control/production.lua +++ b/modules/control/production.lua @@ -33,7 +33,7 @@ ]] local Colors = require 'utils.color_presets' --- @dep utils.color_presets -local format_number = _C.ext_require('util','format_number') --- @dep util +local format_number = _C.format_number --- @dep util local precision_index = defines.flow_precision_index local Production = {} diff --git a/modules/control/rockets.lua b/modules/control/rockets.lua index 63e4928e..0dff7f84 100644 --- a/modules/control/rockets.lua +++ b/modules/control/rockets.lua @@ -27,7 +27,7 @@ local Event = require 'utils.event' --- @dep utils.event local Global = require 'utils.global' --- @dep utils.global -local config = require 'config.rockets' --- @dep config.rockets +local config = require 'config.gui.rockets' --- @dep config.rockets local largest_rolling_avg = 0 for _,avg_over in pairs(config.stats.rolling_avg) do diff --git a/modules/control/warps.lua b/modules/control/warps.lua index 93bf0ea2..897b2bc1 100644 --- a/modules/control/warps.lua +++ b/modules/control/warps.lua @@ -24,7 +24,7 @@ Warps.make_warp_tag(warp_id) local Store = require 'expcore.store' --- @dep expcore.store local Global = require 'utils.global' --- @dep utils.global local Token = require 'utils.token' --- @dep utils.token -local config = require 'config.warps' --- @dep config.warps +local config = require 'config.gui.warps' --- @dep config.warps local Warps = {} diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index beecb309..d16acd5e 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -9,9 +9,9 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles local Store = require 'expcore.store' --- @dep expcore.store local Game = require 'utils.game' --- @dep utils.game local Event = require 'utils.event' --- @dep utils.event -local format_time = _C.ext_require('expcore.common','format_time') --- @dep expcore.common -local config = require 'config.action_buttons' --- @dep config.action_buttons +local config = require 'config.gui.player_list_actions' --- @dep config.gui.player_list_actions local Colors = require 'utils.color_presets' --- @dep utils.color_presets +local format_time = _C.format_time --- @dep expcore.common -- Stores the name of the player a player has selected local selected_player_store = Store.register(function(player) diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index 197699fc..40656e79 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -7,10 +7,10 @@ local Gui = require 'expcore.gui' --- @dep expcore.gui local Roles = require 'expcore.roles' --- @dep expcore.roles local Event = require 'utils.event' --- @dep utils.event -local config = require 'config.rockets' --- @dep config.rockets -local format_time = _C.ext_require('expcore.common','format_time') --- @dep expcore.common +local config = require 'config.gui.rockets' --- @dep config.gui.rockets local Colors = require 'utils.color_presets' --- @dep utils.color_presets local Rockets = require 'modules.control.rockets' --- @dep modules.control.rockets +local format_time = _C.format_time --- @dep expcore.common local time_formats = { caption = function(value) return format_time(value, {minutes=true, seconds=true}) end, diff --git a/modules/gui/science-info.lua b/modules/gui/science-info.lua index 9c6b794f..da43c749 100644 --- a/modules/gui/science-info.lua +++ b/modules/gui/science-info.lua @@ -7,9 +7,9 @@ local Gui = require 'expcore.gui' --- @dep expcore.gui local Roles = require 'expcore.roles' --- @dep expcore.gui local Event = require 'utils.event' --- @dep utils.event -local format_time = _C.ext_require('expcore.common','format_time') --- @dep expcore.common -local config = require 'config.science' --- @dep config.science +local config = require 'config.gui.science' --- @dep config.gui.science local Production = require 'modules.control.production' --- @dep modules.control.production +local format_time = _C.format_time --- @dep expcore.common local null_time_short = {'science-info.eta-time',format_time(0,{hours=true,minutes=true,seconds=true,time=true,null=true})} local null_time_long = format_time(0,{hours=true,minutes=true,seconds=true,long=true,null=true}) diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index 702f3499..19c3906d 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -7,7 +7,7 @@ local Gui = require 'expcore.gui' --- @dep expcore.gui local Event = require 'utils.event' --- @dep utils.event local Roles = require 'expcore.roles' --- @dep expcore.roles -local config = require 'config.tasks' --- @dep config.tasks +local config = require 'config.gui.tasks' --- @dep config.gui.tasks local Tasks = require 'modules.control.tasks' --- @dep modules.control.tasks local format_time = _C.format_time --- @dep expcore.common diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 52b711da..6f25fac1 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -11,7 +11,7 @@ local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game local Roles = require 'expcore.roles' --- @dep expcore.roles local Colors = require 'utils.color_presets' --- @dep utils.color_presets -local config = require 'config.warps' --- @dep config.warps +local config = require 'config.gui.warps' --- @dep config.gui.warps local Warps = require 'modules.control.warps' --- @dep modules.control.warps local format_time = _C.format_time --- @dep expcore.common From c9534de86842d45b0bd4ee8b14c59399d92b95fc Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 1 Apr 2020 00:01:40 +0100 Subject: [PATCH 66/81] Updated Docs --- config/expcore/roles.lua | 4 +- docs/addons/Advanced-Start.html | 41 +- docs/addons/Chat-Popups.html | 41 +- docs/addons/Chat-Reply.html | 41 +- docs/addons/Compilatron.html | 41 +- docs/addons/Damage-Popups.html | 41 +- docs/addons/Death-Logger.html | 41 +- docs/addons/Discord-Alerts.html | 47 +- docs/addons/Player-Colours.html | 47 +- docs/addons/Pollution-Grading.html | 41 +- docs/addons/Scorched-Earth.html | 41 +- docs/addons/Spawn-Area.html | 41 +- docs/addons/Tree-Decon.html | 383 ++ docs/addons/greetings.html | 383 ++ docs/commands/Admin-Chat.html | 41 +- docs/commands/Bonus.html | 41 +- docs/commands/Cheat-Mode.html | 41 +- docs/commands/Clear-Inventory.html | 41 +- docs/commands/Debug.html | 41 +- docs/commands/Find.html | 41 +- docs/commands/Help.html | 41 +- docs/commands/Home.html | 41 +- docs/commands/Interface.html | 41 +- docs/commands/Jail.html | 41 +- docs/commands/Kill.html | 41 +- docs/commands/Me.html | 41 +- docs/commands/Rainbow.html | 41 +- docs/commands/Repair.html | 41 +- docs/commands/Reports.html | 41 +- docs/commands/Roles.html | 47 +- docs/commands/Spawn.html | 41 +- docs/commands/Tag.html | 41 +- docs/commands/Teleport.html | 41 +- docs/commands/Warnings.html | 41 +- docs/config.ld | 2 +- docs/configs/Advanced-Start.html | 41 +- docs/configs/Bonuses.html | 41 +- docs/configs/Chat-Reply.html | 41 +- docs/configs/Commands-Auth-Admin.html | 41 +- docs/configs/Commands-Auth-Roles.html | 41 +- .../Commands-Auth-Runtime-Disable.html | 41 +- docs/configs/Commands-Parse-Roles.html | 41 +- docs/configs/Commands-Parse.html | 41 +- docs/configs/Compilatron.html | 41 +- docs/configs/Death-Logger.html | 41 +- docs/configs/Discord-Alerts.html | 41 +- docs/configs/File-Loader.html | 41 +- docs/configs/Permission-Groups.html | 41 +- docs/configs/Player-List.html | 47 +- docs/configs/Pollution-Grading.html | 41 +- docs/configs/Popup-Messages.html | 41 +- docs/configs/Preset-Player-Colours.html | 41 +- docs/configs/Repair.html | 41 +- docs/configs/Rockets.html | 41 +- docs/configs/Roles.html | 41 +- docs/configs/Science.html | 41 +- docs/configs/Scorched-Earth.html | 41 +- docs/configs/Spawn-Area.html | 41 +- docs/configs/Tasks.html | 41 +- docs/configs/Warnings.html | 41 +- docs/configs/Warps.html | 41 +- docs/control/Jail.html | 41 +- docs/control/Production.html | 389 +- docs/control/Reports.html | 41 +- docs/control/Rockets.html | 41 +- docs/control/Tasks.html | 41 +- docs/control/Warnings.html | 41 +- docs/control/Warps.html | 69 +- docs/core/Async.html | 605 +++ docs/core/Commands.html | 952 +++- docs/core/Common-Library.html | 2600 +++++----- docs/core/Common.html | 2759 ++++++++++ docs/core/Groups.html | 1435 ++++++ docs/core/Gui.html | 4560 +++++++++++------ docs/core/Permissions-Groups.html | 279 +- docs/core/Roles.html | 470 +- docs/core/Store.html | 41 +- docs/guis/Player-List.html | 258 +- docs/guis/Readme.html | 735 +++ docs/guis/Rocket-Info.html | 215 +- docs/guis/Science-Info.html | 109 +- docs/guis/Task-List.html | 111 +- docs/guis/Warps-List.html | 109 +- docs/guis/server-ups.html | 444 ++ docs/index.html | 160 +- docs/modules/Gui.html | 4130 ++++++++++++++- docs/modules/control.html | 97 +- .../modules.addons.station-auto-name.html | 300 ++ docs/modules/overrides.debug.html | 661 +++ docs/modules/overrides.math.html | 360 ++ docs/modules/overrides.table.html | 2015 ++++++++ docs/modules/utils.event.html | 47 +- docs/modules/utils.event_core.html | 41 +- docs/modules/utils.task.html | 41 +- docs/topics/license.html | 41 +- docs/topics/readme.md.html | 43 +- expcore/async.lua | 92 +- expcore/commands.lua | 695 ++- expcore/common.lua | 501 +- expcore/gui.lua | 2 +- expcore/gui/_require.lua | 131 + expcore/gui/core_defines.lua | 2 +- expcore/gui/left_flow.lua | 4 +- expcore/gui/prototype.lua | 164 +- expcore/gui/require.lua | 8 - expcore/gui/top_flow.lua | 2 +- expcore/permission_groups.lua | 262 +- expcore/roles.lua | 661 ++- modules/addons/greetings.lua | 3 +- modules/commands/admin-chat.lua | 2 +- modules/commands/cheat-mode.lua | 2 +- modules/commands/interface.lua | 2 +- modules/commands/roles.lua | 4 +- modules/commands/teleport.lua | 6 +- modules/gui/rocket-info.lua | 2 +- 115 files changed, 23355 insertions(+), 6604 deletions(-) create mode 100644 docs/addons/Tree-Decon.html create mode 100644 docs/addons/greetings.html create mode 100644 docs/core/Async.html create mode 100644 docs/core/Common.html create mode 100644 docs/core/Groups.html create mode 100644 docs/guis/Readme.html create mode 100644 docs/guis/server-ups.html create mode 100644 docs/modules/modules.addons.station-auto-name.html create mode 100644 docs/modules/overrides.debug.html create mode 100644 docs/modules/overrides.math.html create mode 100644 docs/modules/overrides.table.html create mode 100644 expcore/gui/_require.lua delete mode 100644 expcore/gui/require.lua diff --git a/config/expcore/roles.lua b/config/expcore/roles.lua index ef3e1c51..236fa347 100644 --- a/config/expcore/roles.lua +++ b/config/expcore/roles.lua @@ -170,7 +170,7 @@ Roles.new_role('Veteran','Vet') :allow{ 'command/chat-bot', } -:set_auto_promote_condition(function(player) +:set_auto_assign_condition(function(player) if player.online_time > 10*216000 then return true end @@ -198,7 +198,7 @@ Roles.new_role('Regular','Reg') 'command/go-to-spawn', 'command/me', } -:set_auto_promote_condition(function(player) +:set_auto_assign_condition(function(player) if player.online_time > 3*216000 then return true end diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index e06593f6..1d717318 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -348,7 +347,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index 7cb0c9b2..7f17c3a9 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -349,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index 6c368f68..d7927bc8 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -376,7 +375,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index 135ff83a..5b569aae 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -57,10 +57,12 @@ + + @@ -68,13 +70,13 @@ @@ -97,8 +99,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -585,7 +584,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index df0b8737..48df3a68 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -349,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index 4f94aece..a7b1b937 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -404,7 +403,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index 12bccc87..78f0bcd6 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -247,7 +246,7 @@
    - + @@ -323,8 +322,8 @@
    - # - resources.color_presets + # + utils.color_presets
    @@ -460,7 +459,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index 0682c770..a9b88d40 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -241,7 +240,7 @@
    - + @@ -267,8 +266,8 @@
    - # - resources.color_presets + # + utils.color_presets
    @@ -404,7 +403,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index 8ecf95bf..d7166cc9 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -320,7 +319,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index 84ea1706..464c0bf3 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -404,7 +403,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 9cd696ab..27174f1c 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -56,10 +56,12 @@ + + @@ -67,13 +69,13 @@ @@ -96,8 +98,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -376,7 +375,7 @@ generated by LDoc diff --git a/docs/addons/Tree-Decon.html b/docs/addons/Tree-Decon.html new file mode 100644 index 00000000..1ae7cd94 --- /dev/null +++ b/docs/addons/Tree-Decon.html @@ -0,0 +1,383 @@ + + + + + + + + Tree-Decon addon + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    Tree-Decon addon

    +

    Makes trees which are marked for decon "decay" quickly to allow faster building

    +

    + + + + + + + + + + + +
    utils.game
    resources.color_presetsutils.color_presets
    expcore.common
    resources.color_presetsutils.color_presets
    utils.game
    + +

    Dependencies

    + + + + + + + + + + + + + + + + +
    utils.event
    utils.game
    utils.global
    expcore.roles
    + + +
    + + +

    Dependencies

    +
    +
    +
    +
    + # + utils.event +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.game +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.global +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + expcore.roles +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + diff --git a/docs/addons/greetings.html b/docs/addons/greetings.html new file mode 100644 index 00000000..88bcabfb --- /dev/null +++ b/docs/addons/greetings.html @@ -0,0 +1,383 @@ + + + + + + + + greetings addon + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    greetings addon

    +

    Greets players on join

    +

    + + + + + + + + + + + + + +

    Dependencies

    + + + + + + + + + + + + + + + + +
    utils.event
    utils.event
    config.join_messages
    utils.global
    + + +
    + + +

    Dependencies

    +
    +
    +
    +
    + # + utils.event +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.event +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + config.join_messages +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.global +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 7967ea77..e2928b14 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -388,7 +387,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index f0b1fc7b..b4acd3f8 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -500,7 +499,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index 680b91e8..bd44f024 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -361,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index 7026f517..8c73ddea 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -388,7 +387,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index 6667e00b..dc8bd630 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -365,7 +364,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index e95e5332..fa39eb7d 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -360,7 +359,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index deb9aa2a..8d75f6db 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -404,7 +403,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index e9b13bfd..512a2ee6 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -458,7 +457,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index 89212f3b..2f43cbd6 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -416,7 +415,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 2c670b45..f7cdeb46 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -611,7 +610,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index f6e57348..085d3e43 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -389,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index 59c4534a..c8286186 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -360,7 +359,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index 6c90fe3f..38c038a6 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -388,7 +387,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index 004ec4bd..0a156f7b 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -76,13 +76,13 @@ @@ -111,10 +111,12 @@ + + @@ -123,8 +125,10 @@

    Guis

    @@ -135,7 +139,6 @@

    Configs

    @@ -168,18 +172,13 @@

    Modules

    @@ -321,7 +320,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index 2f71921c..88e9d0d0 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -585,7 +584,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index ba0318c7..9ca693d6 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -250,7 +249,7 @@ expcore.roles - resources.color_presets + utils.color_presets @@ -334,8 +333,8 @@
    - # - resources.color_presets + # + utils.color_presets
    @@ -557,7 +556,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index fda9f645..479f2750 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -389,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index 9cf7157a..c21383cd 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -443,7 +442,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index e9131888..b343424b 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -484,7 +483,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index ac587916..ab2e9aed 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -77,13 +77,13 @@ @@ -112,10 +112,12 @@ + + @@ -124,8 +126,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -569,7 +568,7 @@ generated by LDoc diff --git a/docs/config.ld b/docs/config.ld index 01c7486c..43e5bfdc 100644 --- a/docs/config.ld +++ b/docs/config.ld @@ -2,7 +2,7 @@ file = '../' dir = '../docs' project = 'ExpGaming Scenario' title = 'ExpGaming Scenario' -description = 'Explosive Gaming\'s server scenario for 0.17' +description = 'Explosive Gaming\'s server scenario for 0.18' convert_opt = true sort = false diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index 75ce3491..bb433438 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -506,7 +505,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index cc4d5595..ed9c3bd1 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -42,7 +42,6 @@

    Configs

    @@ -74,13 +74,13 @@ @@ -109,10 +109,12 @@ + + @@ -121,8 +123,10 @@

    Guis

    @@ -160,18 +164,13 @@

    Modules

    @@ -237,7 +236,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index d7ae726a..f7c4bca2 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -51,7 +51,6 @@

    Configs

    @@ -83,13 +83,13 @@ @@ -118,10 +118,12 @@ + + @@ -130,8 +132,10 @@

    Guis

    @@ -169,18 +173,13 @@

    Modules

    @@ -485,7 +484,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index 4a48d6da..9da0f411 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -294,7 +293,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index ed1c5b7f..477cb804 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -320,7 +319,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index e72d1a81..1636ab35 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -51,7 +51,6 @@

    Configs

    @@ -83,13 +83,13 @@ @@ -118,10 +118,12 @@ + + @@ -130,8 +132,10 @@

    Guis

    @@ -169,18 +173,13 @@

    Modules

    @@ -442,7 +441,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index f9d62d80..9d4292ca 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -354,7 +353,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index d1d21e74..234392ad 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -338,7 +337,7 @@ see ./expcore/commands.lua for more details

    generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index 7dc0e1b5..dec0e529 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -354,7 +353,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index ab9a69db..67857dec 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -416,7 +415,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index 40ee9ed3..5ea02120 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -42,7 +42,6 @@

    Configs

    @@ -74,13 +74,13 @@ @@ -109,10 +109,12 @@ + + @@ -121,8 +123,10 @@

    Guis

    @@ -160,18 +164,13 @@

    Modules

    @@ -237,7 +236,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 11aeb9af..3a9716cf 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -42,7 +42,6 @@

    Configs

    @@ -74,13 +74,13 @@ @@ -109,10 +109,12 @@ + + @@ -121,8 +123,10 @@

    Guis

    @@ -160,18 +164,13 @@

    Modules

    @@ -240,7 +239,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index 6329eb61..3abffdaa 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -295,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index 2d23727d..cfda4261 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -51,7 +51,6 @@

    Configs

    @@ -83,13 +83,13 @@ @@ -118,10 +118,12 @@ + + @@ -130,8 +132,10 @@

    Guis

    @@ -169,18 +173,13 @@

    Modules

    @@ -268,7 +267,7 @@ modules.control.jail - resources.color_presets + utils.color_presets expcore.common @@ -504,8 +503,8 @@
    - # - resources.color_presets + # + utils.color_presets
    @@ -812,7 +811,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index 2c6dc312..6be165c4 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -384,7 +383,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index bf97ecf9..4f9f85b0 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -414,7 +413,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index 3fd3eca5..723391f4 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -324,7 +323,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index 82dcaa12..e8582c36 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -414,7 +413,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index a318f0cd..0db5696a 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -834,7 +833,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index c324a6ac..a6816311 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -292,7 +291,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index f5dca812..332659e6 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -354,7 +353,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index f011372b..a55e5c6b 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -388,7 +387,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index fac7d663..66357213 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -744,7 +743,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index 4e84ef99..f3bf9416 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -384,7 +383,7 @@ generated by LDoc diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index 09b6a980..77d8481e 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -355,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index 0353eba6..81f0ffec 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,7 +50,6 @@

    Configs

    @@ -82,13 +82,13 @@ @@ -117,10 +117,12 @@ + + @@ -129,8 +131,10 @@

    Guis

    @@ -168,18 +172,13 @@

    Modules

    @@ -774,7 +773,7 @@ generated by LDoc diff --git a/docs/control/Jail.html b/docs/control/Jail.html index 4f02fcb1..f66c2789 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -66,13 +66,13 @@ @@ -87,10 +87,12 @@ + + @@ -99,8 +101,10 @@

    Guis

    @@ -138,7 +142,6 @@

    Configs

    @@ -171,18 +175,13 @@

    Modules

    @@ -1208,7 +1207,7 @@ generated by LDoc diff --git a/docs/control/Production.html b/docs/control/Production.html index 301380da..66ab08bb 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -42,9 +42,9 @@

    Sections

    @@ -66,13 +66,13 @@ @@ -87,10 +87,12 @@ + + @@ -99,8 +101,10 @@

    Guis

    @@ -138,7 +142,6 @@

    Configs

    @@ -171,18 +175,13 @@

    Modules

    @@ -205,9 +204,9 @@

    Jump to Section

    @@ -275,7 +274,7 @@ - resources.color_presets + utils.color_presets util @@ -284,6 +283,22 @@ +

    Formating

    + + + + + + + + + + + + +
    get_color(clamp, active_value, passive_value)Returns a color value bassed on the value that was given
    format_number(value)Returns three parts used to format a number
    + +

    Precision

    @@ -334,22 +349,6 @@
    - - -

    Formating

    - - - - - - - - - - - - -
    get_color(clamp, active_value, passive_value)Returns a color value bassed on the value that was given
    format_number(value)Returns three parts used to format a number

    @@ -360,8 +359,8 @@
    - # - resources.color_presets + # + utils.color_presets
    @@ -400,6 +399,159 @@ + + + + + + +
    + +

    Formating

    +
    +
    +
    +
    + # + get_color(clamp, active_value, passive_value) +
    +
    +
    +
    + +

    Returns a color value bassed on the value that was given

    +

    + + + Parameters: + +
      + + + + + +
    • + + clamp + + : + + (number) + + value which seperates the different colours + +
    • + + + + + +
    • + + active_value + + : + + (number) + + first value tested, tested against clamp + +
    • + + + + + +
    • + + passive_value + + : + + (number) + + second value tested, tested against 0 + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + contains r,g,b keys +
    • +
    + + + + + + + + + +
    +
    +
    +
    + # + format_number(value) +
    +
    +
    +
    + +

    Returns three parts used to format a number

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (number) + + the value to format + +
    • + + +
    + + + + + Returns: +
      +
    • + (string) + the sign for the number +
    • +
    • + (string) + the surfix for any unit used +
    • +
    + + + @@ -1154,159 +1306,6 @@ - - - - - - -
    -
    -

    Formating

    -
    -
    -
    -
    - # - get_color(clamp, active_value, passive_value) -
    -
    -
    -
    - -

    Returns a color value bassed on the value that was given

    -

    - - - Parameters: - -
      - - - - - -
    • - - clamp - - : - - (number) - - value which seperates the different colours - -
    • - - - - - -
    • - - active_value - - : - - (number) - - first value tested, tested against clamp - -
    • - - - - - -
    • - - passive_value - - : - - (number) - - second value tested, tested against 0 - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - contains r,g,b keys -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - format_number(value) -
    -
    -
    -
    - -

    Returns three parts used to format a number

    -

    - - - Parameters: - -
      - - - - - -
    • - - value - - : - - (number) - - the value to format - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the sign for the number -
    • -
    • - (string) - the surfix for any unit used -
    • -
    - - - @@ -1329,7 +1328,7 @@ generated by LDoc
    diff --git a/docs/control/Reports.html b/docs/control/Reports.html index 349a872c..09e64549 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -66,13 +66,13 @@ @@ -87,10 +87,12 @@ + + @@ -99,8 +101,10 @@

    Guis

    @@ -138,7 +142,6 @@

    Configs

    @@ -171,18 +175,13 @@

    Modules

    @@ -1110,7 +1109,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index 2f5efd39..d1bcf823 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -65,13 +65,13 @@ @@ -86,10 +86,12 @@ + + @@ -98,8 +100,10 @@

    Guis

    @@ -137,7 +141,6 @@

    Configs

    @@ -170,18 +174,13 @@

    Modules

    @@ -984,7 +983,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index 440f1c35..d8fe98bf 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -65,13 +65,13 @@ @@ -86,10 +86,12 @@ + + @@ -98,8 +100,10 @@

    Guis

    @@ -137,7 +141,6 @@

    Configs

    @@ -170,18 +174,13 @@

    Modules

    @@ -998,7 +997,7 @@ Tasks.update_task(task_id,'We need more iron!',game. generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index 32c13b69..7465e015 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -65,13 +65,13 @@ @@ -86,10 +86,12 @@ + + @@ -98,8 +100,10 @@

    Guis

    @@ -137,7 +141,6 @@

    Configs

    @@ -170,18 +174,13 @@

    Modules

    @@ -1465,7 +1464,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index 5a52b7df..f3a3b9f2 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -66,13 +66,13 @@ @@ -87,10 +87,12 @@ + + @@ -99,8 +101,10 @@

    Guis

    @@ -138,7 +142,6 @@

    Configs

    @@ -171,18 +175,13 @@

    Modules

    @@ -274,9 +273,6 @@ Warps.make_warp_tag(warp_id) config.warps - - expcore.common - @@ -463,31 +459,6 @@ Warps.make_warp_tag(warp_id) - - - - - - - -
    -
    -
    - # - expcore.common -
    -
    -
    -
    - - - - - - - - - @@ -1563,7 +1534,7 @@ Warps.make_warp_tag(warp_id) generated by LDoc
    diff --git a/docs/core/Async.html b/docs/core/Async.html new file mode 100644 index 00000000..6a6a6a2d --- /dev/null +++ b/docs/core/Async.html @@ -0,0 +1,605 @@ + + + + + + + + Async core + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    Async core

    +

    Core Module - Async +- An extention of task and token to allow a single require to register and run async functions.

    +

    + + + + + + +

    Usage

    +
    
    +-- To use Async you must register the allowed functions when the file is loaded, often this will just be giving access to
    +-- some functions within a module if you expect that at part may be blocked by in game permissions or a custom system you have made
    +-- you may also want to register functions that you want to have a time delay, such as waiting 2 seconds before printing a message
    +
    +-- When player.admin is called (either command or gui element event) by a player who isnt admin then it will error
    +-- here we register the function to promote the player so that it will run async and outside the player scope
    +local promote_player =
    +Async.register(function(player)
    +    player.admin = true
    +end)
    +
    +-- This will allow us to bypass the error by running one tick later outside of any player scope
    +Async(promote_player,game.player)
    +
    +-- Here we make an sync function that we want to have a delay, note the delay is not defined here
    +local print_message =
    +Async.register(function(player,message)
    +    player.print(message)
    +end)
    +
    +-- We can then call the async function with a delay using the wait function
    +Async.wait(60, print_message, game.player, 'One second has passed!')
    + + + + + +
    + +

    Dependencies

    + + + + + + + + + + +
    utils.task
    utils.token
    + + +

    Functions

    + + + + + + + + + + + + + + + + +
    register(callback)Register a new async function, must called when the file is loaded
    run(token[, ...])Runs an async function, you may supply any number of arguments as required by that function
    wait(ticks, token[, ...])Runs an async function after the given number of ticks, you may supply any number of arguments as required by that function
    + + +
    + + +

    Dependencies

    +
    +
    +
    +
    + # + utils.task +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.token +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +

    Functions

    +
    +
    +
    +
    + # + register(callback) +
    +
    +
    +
    + +

    Register a new async function, must called when the file is loaded

    +

    + + + Parameters: + +
      + + + + + +
    • + + callback + + : + + (function) + + the function that can be called as an async function + +
    • + + +
    + + + + + Returns: +
      +
    • + (string) + the uid of the async function which can be passed to Async.run and Async.wait +
    • +
    + + + + + + + + Usage: +
    -- Registering a function to set the admin state of a player
    +local set_admin =
    +Async.register(function(player, state)
    +    if player.valid then
    +        player.admin = state
    +    end
    +end)
    +
    -- Registering a function to print to a player
    +local print_to_player =
    +Async.register(function(player, message)
    +    if player.valid then
    +        player.print(message)
    +    end
    +end)
    + + +
    +
    +
    +
    + # + run(token[, ...]) +
    +
    +
    +
    + +

    Runs an async function, you may supply any number of arguments as required by that function

    +

    + + + Parameters: + +
      + + + + + +
    • + + token + + : + + (string) + + the token of the async function you want to run + +
    • + + + + + +
    • + + ... + + : + + (any) + + the other params that you want to pass to your function + + (optional) +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Make a player admin regardless of if you are admin
    +Async.run(set_admin, player, true)
    + + +
    +
    +
    +
    + # + wait(ticks, token[, ...]) +
    +
    +
    +
    + +

    Runs an async function after the given number of ticks, you may supply any number of arguments as required by that function

    +

    + + + Parameters: + +
      + + + + + +
    • + + ticks + + : + + (number) + + the number of ticks that you want the function to run after + +
    • + + + + + +
    • + + token + + : + + (string) + + the token of the async function you want to run + +
    • + + + + + +
    • + + ... + + : + + (any) + + the other params that you want to pass to your function + + (optional) +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Print a message to a player after 5 seconds
    +Async.wait(300, print_to_player, 'Hello, World!')
    + + +
    +
    + + + + + + + + + + diff --git a/docs/core/Commands.html b/docs/core/Commands.html index 26e2e30e..512c965a 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -42,6 +42,8 @@

    Sections

    @@ -89,10 +91,12 @@ + + @@ -101,8 +105,10 @@

    Guis

    @@ -140,7 +146,6 @@

    Configs

    @@ -173,18 +179,13 @@

    Modules

    @@ -207,6 +208,8 @@

    Jump to Section

    +
    +

    Tables

    +
    +
    +
    +
    + # + defines +
    +
    +
    +
    + +

    Values returned by the signal functions to cause the command system to react

    +

    + + + Fields: + +
      + + + + + +
    • + + error + + + + + +
    • + + + + + +
    • + + unauthorized + + + + + +
    • + + + + + +
    • + + success + + + + + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + commands +
    +
    +
    +
    + +

    Custom command data will be stored here

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + authorization +
    +
    +
    +
    + +

    Custom function are stored here which control who can use what commands

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + parse_functions +
    +
    +
    +
    + +

    Used to store default functions which are common parse function such as player or number in range

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + _prototype +
    +
    +
    +
    + +

    Used to store functions which gets added to new custom commands

    +

    + + + + + + + + + + + + + + +
    +
    +

    Fields

    +
    +
    +
    +
    + # + authorization_fail_on_error +
    +
    +
    +
    + +

    Set true to have authorize fail if a callback fails to run, more secure

    +

    + + + + + + + + @@ -662,10 +921,6 @@ (function) the callback you want to register as an authenticator - callback param - player: LuaPlayer - the player who is trying to use the command - callback param - command: string - the name of the command which is being used - callback param - flags: table - any flags which have been set for the command - callback param - reject: function(error_message?: string) - call to fail authorize with optional error message @@ -689,6 +944,16 @@ + Usage: +
    -- Test if a command is admin only and if the player is admin
    +local admin_authenticator =
    +Commands.add_authenticator(function(player, command, flags, reject)
    +    if flags.admin_only then
    +        return player.admin or reject('This command is for admins only!')
    +    else
    +        return true
    +    end
    +end)
    @@ -736,7 +1001,7 @@
    • (boolean) - was the callback found and removed + if the callback found and removed successfuly
    @@ -746,6 +1011,9 @@ + Usage: +
    -- Removing the admin authenticator, can not be done dueing runtime
    +Commands.remove_authenticator(admin_authenticator)
    @@ -834,6 +1102,9 @@ + Usage: +
    -- Test if a player can use "repeat-name"
    +local authorized, status = Commands.authorize(game.player, 'repeat-name')
    @@ -850,7 +1121,7 @@
    -

    Gets all commands that a player is allowed to use, game commands not included

    +

    Gets all commands that a player is allowed to use, game commands are not included

    @@ -895,6 +1166,11 @@ + Usage: +
    -- Get the command you are allowed to use
    +local commands = Commands.get(game.player)
    +
    -- Get all commands that are registered
    +local commands = Commands.get()
    @@ -902,13 +1178,13 @@
    # - search(keyword[, allowed_player]) + search(keyword[, player])
    -

    Searches command names and help messages to find possible commands, game commands included

    +

    Searches command names and help messages to find possible commands, game commands are included

    @@ -928,7 +1204,7 @@ (string) - the word which you are trying to find + the word which you are trying to find in your search @@ -938,7 +1214,7 @@
  • - allowed_player + player : @@ -969,6 +1245,11 @@ + Usage: +
    -- Get all commands which "repeat"
    +local commands = Commands.search('repeat')
    +
    -- Get all commands which "repeat" and you are allowed to use
    +local commands = Commands.search('repeat', game.player)
  • @@ -985,8 +1266,8 @@
    -

    Adds a parse function which can be called by name rather than callback (used in add_param) - nb: this is not needed as you can use the callback directly this just allows it to be called by name

    +

    Adds a parse function which can be called by name (used in add_param) +nb: this is not required as you can use the callback directly this just allows it to be called by name

    @@ -1023,10 +1304,6 @@ (function) the callback that is ran to parse the input - parse param - input: string - the input given by the user for this param - parse param - player: LuaPlayer - the player who is using the command - parse param - reject: function(error_message) - use this function to send a error to the user and fail running - parse return - the value that will be passed to the command callback, must not be nil and if reject then command is not run @@ -1050,6 +1327,18 @@ + Usage: +
    -- Adding a parse to validate ints in a given range
    +Commands.add_parse('number-range-int', function(input, player, reject, range_min, range_max)
    +    local rtn = tonumber(input) and math.floor(tonumber(input)) or nil -- converts input to number
    +    if not rtn or rtn < range_min or rtn > range_max then
    +        -- the input is either not a number or is outside the range
    +        return reject('Number entered is not in range: '..range_min..', '..range_max)
    +    else
    +        -- returns the input as a number rather than a string, thus the param is now the correct type
    +        return rtn
    +    end
    +end)
    @@ -1100,6 +1389,9 @@ + Usage: +
    -- Removing a parse
    +Commands.remove_parse('number-range-int')
    @@ -1133,7 +1425,7 @@ (string) - the name of the parse to call, must be registered and cant be a function + the name of the parse to call, must be registered parse @@ -1149,7 +1441,7 @@ (string) - string the input to pass to the parse, will always be a but might not be the original input + string the input to pass to the parse, must be a string but not necessarily the original input @@ -1165,7 +1457,7 @@ (LuaPlayer) - the player that is calling using the command + the player that is using the command @@ -1205,6 +1497,10 @@ + Usage: +
    -- Parsing a int in a given range
    +local parsed_input = Commands.parse('number-range-int', '7', player, reject, 1, 10) -- valid range 1 to 10
    +
    @@ -1221,7 +1517,7 @@
    -

    Creates a new command object to added details to, note this does not register the command to the game

    +

    Creates a new command object to added details to, note this does not register the command to the game api

    @@ -1281,6 +1577,10 @@ + Usage: +
    -- Define a new command
    +local command =
    +Commands.new_command('repeat-name', 'Will repeat you name a number of times in chat.')
    @@ -1364,10 +1664,6 @@ extra args you want to pass to the parse function; for example if the parse is general use - parse param - input: string - the input given by the user for this param - parse param - player: LuaPlayer - the player who is using the command - parse param - reject: function(error_message) - use this function to send a error to the user and fail running - parse return - the value that will be passed to the command callback, must not be nil and if reject then command is not run (optional) @@ -1392,6 +1688,14 @@ + Usage: +
    -- Adding a param which has an parse defined
    +command:add_param('repeat-count', false, 'number-range-int', 1, 5)
    +
    -- Adding a param which has a custom parse, see Commands.add_parse for details
    +command:add_param('smiley', true, function(input, player, reject)
    +    if not input then return end
    +    return input:lower() == 'true' or input:lower() == 'yes' or false
    +end)
    @@ -1405,7 +1709,7 @@
    -

    Adds default values to params only matters if the param is optional, if default value is a function it is called with param player

    +

    Add default values to params, only as an effect if the param is optional, if default value is a function it is called with acting player

    @@ -1425,8 +1729,7 @@ (table) - table a keyed by the name of the param with the value as the default value {paramName=defaultValue} - callback param - player: LuaPlayer - the player using the command, default value does not need to be a function callback + table which is keyed by the name of the param and the value is the default value @@ -1450,6 +1753,15 @@ + Usage: +
    -- Adding default values
    +command:set_defaults{
    +    smiley = false,
    +    -- not in example just used to show arguments given
    +    player_name = function(player)
    +        return player.name
    +    end
    +}
    @@ -1457,7 +1769,7 @@
    # - Commands._prototype:set_flag(name, value) + Commands._prototype:set_flag(name[, value=true])
    @@ -1483,7 +1795,7 @@ (string) - the name of the tag to be added; used to keep flags separate + the name of the tag to be added, set to true if no value is given @@ -1500,8 +1812,8 @@ (any) the tag that you want can be anything that the authenticators are expecting - nb: if value is nil then name will be assumed as the value and added at a numbered index + (default: true) @@ -1524,6 +1836,11 @@ + Usage: +
    -- Setting a custom flag
    +command:set_flag('admin_only', true)
    +
    -- When value is true it does not need to be given
    +command:set_flag('admin_only')
    @@ -1537,7 +1854,7 @@
    -

    Adds an alias or multiple that will also be registered with the same callback, eg /teleport can be /tp with both working

    +

    Adds an alias, or multiple, that will also be registered with the same callback, eg /teleport can be used as /tp

    @@ -1582,7 +1899,8 @@ Usage: -
    command:add_alias('aliasOne','aliasTwo','etc')
    +
    -- Added multiple aliases to a command
    +command:add_alias('name', 'rname')
    @@ -1597,8 +1915,8 @@

    Enables auto concatenation of any params on the end so quotes are not needed for last param - nb: this will disable max param checking as they will be concatenated onto the end of that last param - this can be useful for reasons or longs text, can only have one per command

    +nb: this will disable max param checking as they will be concatenated onto the end of that last param +this can be useful for reasons or longs text, can only have one per command

    @@ -1619,6 +1937,9 @@ + Usage: +
    -- Enable auto concat for a command
    +command:enable_auto_concat()
    @@ -1632,8 +1953,8 @@
    -

    Adds the callback to the command and registers all aliases, params and help message with the game - nb: this must be the last function ran on the command and must be done for the command to work

    +

    Adds the callback to the command and registers all aliases, params and help message with the game api +nb: this must be the last function ran on the command and must be done for the command to work

    @@ -1654,9 +1975,6 @@ (function) the callback for the command, will receive the player running command, and params added with add_param - callback param - player: LuaPlayer - the player who used the command - callback param - ... - any params which were registered with add_param in the order they where registered - callback param - raw: string - the raw input from the user, comes after every param added with add_param @@ -1673,6 +1991,16 @@ + Usage: +
    -- Registering your command to the game api
    +command:register(function(player, repeat_count, smiley, _)
    +    local msg = ') '..player.name
    +    if smiley then msg = ':'..msg end
    +
    +    for 1 = 1,repeat_count do
    +        Command.print(1..msg)
    +    end
    +end)
    @@ -1683,15 +2011,14 @@
    # - error([error_message][, play_sound]) + error([error_message=''][, play_sound=utility/wire_pickup])
    -

    Sends an error message to the player and returns a constant to return to command handler to exit execution - nb: this is for non fatal errors meaning there is no log of this event - nb: if reject is giving as a param to the callback use that instead

    +

    Sends an error message to the player and when returned will stop exicution of the command +nb: this is for non fatal errors meaning there is no log of this event, use during register callback

    @@ -1713,7 +2040,7 @@ an optional error message that can be sent to the user - (optional) + (default: '') @@ -1730,7 +2057,7 @@ the sound to play for the error - (optional) + (default: utility/wire_pickup) @@ -1754,7 +2081,8 @@ Usage: -
    return Commands.error()
    +
    -- Send an error message to the player, and stops further code running
    +return Commands.error('The player you selected is offline')
    @@ -1769,7 +2097,7 @@

    Sends an error to the player and logs the error, used with pcall within command handler please avoid direct use - nb: use error(error_message) within your callback to trigger do not trigger directly as the handler may still continue

    +nb: use error(error_message) within your callback to trigger do not trigger directly as code exictuion may still continue

    @@ -1845,6 +2173,12 @@ + Usage: +
    -- Used in the command system to log handler errors
    +local success, err = pcall(command_data.callback, player, unpack(params))
    +if Commands.internal_error(success, command_data.name, err) then
    +    return command_log(player, command_data, 'Internal Error: Command Callback Fail', raw_params, command_event.parameter, err)
    +end
    @@ -1859,7 +2193,7 @@

    Sends a value to the player, followed by a command complete message - nb: either return a value from your callback to trigger or return the return of this to prevent two messages

    +nb: returning any value from your callback will trigger this function, return this function to prevent duplicate messages

    @@ -1904,6 +2238,80 @@ + Usage: +
    -- Print a custom success message
    +return Commands.success('Your message has been printed')
    +
    -- Returning the value has the same result
    +return 'Your message has been printed'
    + + + +
    +
    +
    + # + print(value, colour) +
    +
    +
    +
    + +

    Sends a value to the player, different to success as this does not signal the end of your command

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (any) + + the value that you want to return to the player + +
    • + + + + + +
    • + + colour + + : + + (table) + + the colour of the message that the player sees + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Output a message to the player
    +Commands.print('Your command is in progress')
    @@ -1954,6 +2362,8 @@ + Usage: +
    Commands.run_command(event)
    @@ -1972,7 +2382,7 @@ generated by LDoc
    diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index 6b2cd701..8b86b626 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -42,7 +42,10 @@

    Sections

    @@ -50,13 +53,13 @@ @@ -85,10 +88,12 @@ + + @@ -97,8 +102,10 @@

    Guis

    @@ -136,7 +143,6 @@

    Configs

    @@ -169,18 +176,13 @@

    Modules

    @@ -203,7 +205,10 @@

    Jump to Section

    @@ -244,7 +249,7 @@ - resources.color_presets + utils.color_presets utils.game @@ -256,25 +261,77 @@ -

    Functions

    +

    Type Checking

    - + - + - + + + + + + + + + - - + + + + + + + + + + + + +
    type_check(value[, test_type=nil])Compare types faster for faster validation of paramsAsserts the argument is of type test_type
    type_check_error(value, test_type, error_message, level)type_error(value, test_type, error_message, level) Raises an error if the value is of the wrong type
    param_check(value, test_type, param_name, param_number)multi_type_check(value, test_types)Asserts the argument is one of type test_types
    multi_type_error(value, test_types, error_message, level)Raises an error if the value is of the wrong type
    validate_argument_type(value, test_type, param_name, param_number) Raises an error when the value is the incorrect type, uses a consistent error message format
    player_return(value[, colour=defines.colour.white][, player=game.player])Will return a value of any type to the player/server console, allows colour for in-game playersvalidate_argument_multi_type(value, test_types, param_name, param_number)Raises an error when the value is the incorrect type, uses a consistent error message format
    error_if_runtime()Will raise an error if called during runtime
    error_if_runetime_closure(func)Will raise an error if the function is a closure
    + + +

    Value Returns

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -285,8 +342,40 @@ - - + + + + + + + + + + + + +
    string_contains(s, contains)Tests if a string contains a given substring.
    resolve_value(value)Used to resolve a value that could also be a function returning that value
    get_actor()Returns a valid string with the name of the actor of a command.
    cast_bool(var)Converts a varible into its boolean value, nil and false return false
    ternary(c, t, f)Returns either the second or third argument based on the first argument
    comma_value(n)Returns a string for a number with comma seperators
    set_and_return(tbl, key, value)Sets a table element to value while also returning value.
    write_json(path, tbl)Calls a require that will not error if the file is not found
    ext_require(path, ...)Calls a require and returns only the keys given, file must return a tableget_file_path([offset=0])Returns a desync safe file path for the current file
    enum(tbl)Converts a table to an enum
    auto_complete(options, input[, use_key=false][, rtn_key=false])Returns the closest match to the input
    + + +

    Formating

    + + + + + + + + + + + + + + + + + + @@ -296,6 +385,14 @@ string will return a string not a locale string when a denomination is false it will overflow into the next one + +
    format_chat_colour(message, color)Returns a message with valid chat tags to change its colour
    format_chat_colour_localized(message, color)Returns a message with valid chat tags to change its colour, using localization
    format_chat_player_name(player[, raw_string=false])Returns the players name in the players color
    player_return(value[, 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
    format_time(ticks, options)
    + + +

    Factorio

    + + + @@ -313,66 +410,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    move_items(items[, surface=navies][, position={0][, radius=32][, chest_type=iron-chest]) Moves items to the position and stores them in the closest entity of the type givenclear_flying_text(surface) Clears all flying text entities on a surface
    string_contains(s, contains)Tests if a string contains a given substring.
    extract_keys(tbl, ...)Extracts certain keys from a table
    enum(tbl)Converts a table to an enum
    auto_complete(options, input[, use_key=false][, rtn_key=false])Returns the closest match to the input
    table_values(tbl[, sorted][, as_string])Returns a copy of all of the values in the table.
    table_keys(tbl[, sorted][, as_string])Returns a copy of all of the keys in the table.
    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 alternative than above)
    format_chat_colour(message, color)Returns a message with valid chat tags to change its colour
    format_chat_colour_localized(message, color)Returns a message with valid chat tags to change its colour, using localization
    format_chat_player_name(player[, raw_string=false])Returns the players name in the players color
    get_file_path([offset=0])Returns a desync safe file path for the current file
    array_insert(tbl[, start_index], values)Much faster method for inserting items into an array
    table_insert(tbl[, start_index], tbl2)Much faster method for inserting keys into a table
    resolve_value(value)Used to resolve a value that could also be a function returning that value
    @@ -385,8 +422,8 @@
    - # - resources.color_presets + # + utils.color_presets
    @@ -458,7 +495,7 @@
    -

    Functions

    +

    Type Checking

    @@ -470,7 +507,7 @@
    -

    Compare types faster for faster validation of params

    +

    Asserts the argument is of type test_type

    @@ -540,8 +577,8 @@
    - # - type_check_error(value, test_type, error_message, level) + # + type_error(value, test_type, error_message, level)
    @@ -640,15 +677,193 @@ Usage: -
    type_check_error('foo','number','Value must be a number') -- will raise error "Value must be a number"
    +
    type_error('foo','number','Value must be a number') -- will raise error "Value must be a number"
    - # - param_check(value, test_type, param_name, param_number) + # + multi_type_check(value, test_types) +
    +
    +
    +
    + +

    Asserts the argument is one of type test_types

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + + the variable to check + +
    • + + + + + +
    • + + test_types + + : + + + the type as a table of strings + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if value is one of test_types +
    • +
    + + + + + + + + + +
    +
    +
    +
    + # + multi_type_error(value, test_types, error_message, level) +
    +
    +
    +
    + +

    Raises an error if the value is of the wrong type

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (any) + + the value that you want to test the type of + +
    • + + + + + +
    • + + test_types + + : + + (table) + + the type as a table of strings + +
    • + + + + + +
    • + + error_message + + : + + (string) + + the error message that is returned + +
    • + + + + + +
    • + + level + + : + + (number) + + the level to call the error on (level = 1 means the caller) + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if no error was called +
    • +
    + + + + + + + + Usage: +
    multi_type_error('foo',{'string','table'},'Value must be a string or table') -- will raise error "Value must be a string or table"
    + + +
    +
    +
    +
    + # + validate_argument_type(value, test_type, param_name, param_number)
    @@ -747,21 +962,21 @@ Usage: -
    param_check('foo','number','repeat_count',2) -- will raise error "Invalid param #02 given to <anon>; repeat_count is not of type number"
    +
    validate_argument_type('foo','number','repeat_count',2) -- will raise error "Bad argument #02 to "<anon>"; "repeat_count" is of type string expected number"
    - # - player_return(value[, colour=defines.colour.white][, player=game.player]) + # + validate_argument_multi_type(value, test_types, param_name, param_number)
    -

    Will return a value of any type to the player/server console, allows colour for in-game players

    +

    Raises an error when the value is the incorrect type, uses a consistent error message format

    @@ -779,8 +994,9 @@ : + (any) - any value of any type that will be returned to the player or console + the value that you want to test the type of @@ -790,15 +1006,14 @@
  • - colour + test_types : - (defines.color or string) + (string) - the colour of the text for the player, ignored when printing to console + the types that the value should be - (default: defines.colour.white)
  • @@ -807,15 +1022,116 @@
  • - player + param_name : - (LuaPlayer) + (string) + + the name of the param + +
  • + + + + + +
  • + + param_number + + : + + (number) + + the number param it is + +
  • + + + + + + + + Returns: +
      +
    • + (boolean) + true if no error was raised +
    • +
    + + + + + + + + Usage: +
    validate_argument_type('foo',{'string','table'},'repeat_count',2) -- will raise error "Bad argument #02 to "<anon>"; "repeat_count" is of type string expected string or table"
    + + +
    +
    +
    +
    + # + error_if_runtime() +
    +
    +
    +
    + +

    Will raise an error if called during runtime

    +

    + + + + + + + + + + + + + Usage: +
    error_if_runtime()
    + + +
    +
    +
    +
    + # + error_if_runetime_closure(func) +
    +
    +
    +
    + +

    Will raise an error if the function is a closure

    +

    + + + Parameters: + +
      + + + + + +
    • + + func + + + - the player that return will go to, if no game.player then returns to server - (default: game.player)
    • @@ -832,9 +1148,445 @@ 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
      +
      error_if_runetime_closure(func)
      + + +
    +
    +

    Value Returns

    +
    +
    +
    +
    + # + 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 +
    • +
    + + + + + + + + + +
    +
    +
    +
    + # + resolve_value(value) +
    +
    +
    +
    + +

    Used to resolve a value that could also be a function returning that value

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (any) + + the value which you want to test is not nil and if it is a function then call the function + +
    • + + +
    + + + + + Returns: +
      +
    • + (any) + the value given or returned by value if it is a function +
    • +
    + + + + + + + + Usage: +
    -- Default value handling
    +-- if default value is not a function then it is returned
    +-- if it is a function then it is called with the first argument being self
    +local value = Common.resolve_value(self.defaut_value,self)
    + + +
    +
    +
    +
    + # + get_actor() +
    +
    +
    +
    + +

    Returns a valid string with the name of the actor of a command.

    +

    + + + + + + Returns: +
      +
    • + (string) + the name of the current actor +
    • +
    + + + + + + + + + +
    +
    +
    +
    + # + cast_bool(var) +
    +
    +
    +
    + +

    Converts a varible into its boolean value, nil and false return false

    +

    + + + Parameters: + +
      + + + + + +
    • + + var + + + + + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the boolean form of the varible +
    • +
    + + + + + + + + + +
    +
    +
    +
    + # + ternary(c, t, f) +
    +
    +
    +
    + +

    Returns either the second or third argument based on the first argument

    +

    + + + Parameters: + +
      + + + + + +
    • + + c + + + + + +
    • + + + + + +
    • + + t + + + + + +
    • + + + + + +
    • + + f + + + + + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + comma_value(n) +
    +
    +
    +
    + +

    Returns a string for a number with comma seperators

    +

    + + + Parameters: + +
      + + + + + +
    • + + n + + : + + (credit http) + + //richard.warburton.it + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + set_and_return(tbl, key, value) +
    +
    +
    +
    + +

    Sets a table element to value while also returning value.

    +

    + + + Parameters: + +
      + + + + + +
    • + + tbl + + : + + + table to change the element of + +
    • + + + + + +
    • + + key + + : + + + string + +
    • + + + + + +
    • + + value + + : + + + nil|boolean|number|string|table to set the element to + +
    • + + +
    + + + + + Returns: +
      +
    • + value +
    • +
    + + + + + + +
    @@ -965,14 +1717,14 @@
    - # - ext_require(path, ...) + # + get_file_path([offset=0])
    -

    Calls a require and returns only the keys given, file must return a table

    +

    Returns a desync safe file path for the current file

    @@ -986,29 +1738,71 @@
  • - path + offset : - (string) + (number) - the path that you want to require + the offset in the stack to get, 0 is current file + (default: 0)
  • + + + + + + Returns: +
      +
    • + (string) + the file path +
    • +
    + + + + + + + + + +
    +
    +
    +
    + # + enum(tbl) +
    +
    +
    +
    + +

    Converts a table to an enum

    +

    + + + Parameters: + +
      + +
    • - ... + tbl : - (string) + (table) - the name of the keys that you want returned + table the that will be converted
    • @@ -1021,18 +1815,433 @@ Returns:
      • - the keys in the order given + (table) + the new table that acts like an enum
      + + + + + + +
    +
    +
    +
    + # + auto_complete(options, input[, use_key=false][, rtn_key=false]) +
    +
    +
    +
    + +

    Returns the closest match to the input

    +

    + + + Parameters: + +
      + + + + + +
    • + + options + + : + + (table) + + table a of options for the auto complete + +
    • + + + + + +
    • + + input + + : + + (string) + + string the input that will be completed + +
    • + + + + + +
    • + + use_key + + : + + (boolean) + + when true the keys of options will be used as the options + + (default: false) +
    • + + + + + +
    • + + rtn_key + + : + + (boolean) + + when true the the key will be returned rather than the value + + (default: false) +
    • + + +
    + + + + + Returns: +
      +
    • + the list item found that matches the input +
    • +
    + + + + + + + + + +
    +
    +

    Formating

    +
    +
    +
    +
    + # + format_chat_colour(message, color) +
    +
    +
    +
    + +

    Returns a message with valid chat tags to change its colour

    +

    + + + Parameters: + +
      + + + + + +
    • + + message + + : + + (string) + + the message that will be in the output + +
    • + + + + + +
    • + + color + + : + + (table) + + a color which contains r,g,b as its keys + +
    • + + +
    + + + + + Returns: +
      +
    • + (string) + the message with the color tags included +
    • +
    + + + + + + + + + +
    +
    +
    +
    + # + format_chat_colour_localized(message, color) +
    +
    +
    +
    + +

    Returns a message with valid chat tags to change its colour, using localization

    +

    + + + Parameters: + +
      + + + + + +
    • + + message + + : + + (string or table) + + the message that will be in the output + +
    • + + + + + +
    • + + color + + : + + (table) + + a color which contains r,g,b as its keys + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the message with the color tags included +
    • +
    + + + + + + + + + +
    +
    +
    +
    + # + format_chat_player_name(player[, raw_string=false]) +
    +
    +
    +
    + +

    Returns the players name in the players color

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player to use the name and color of + +
    • + + + + + +
    • + + raw_string + + : + + (boolean) + + when true a is returned rather than a localized string + + (default: false) +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the players name with tags for the players color +
    • +
    + + + + + + + + + +
    +
    +
    +
    + # + player_return(value[, 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: + +
      + + + + + +
    • + + value + + : + + + 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, ignored 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: -
    local extract, param_check = ext_require('expcore.common','extract','param_check') --- @dep expcore.common
    +
    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
    @@ -1113,6 +2322,9 @@ +
    +

    Factorio

    +
    @@ -1592,1144 +2804,6 @@ - -
    -
    -
    - # - 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 -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - extract_keys(tbl, ...) -
    -
    -
    -
    - -

    Extracts certain keys from a table

    -

    - - - Parameters: - -
      - - - - - -
    • - - tbl - - : - - (table) - - table the which contains the keys - -
    • - - - - - -
    • - - ... - - : - - (string) - - the names of the keys you want extracted - -
    • - - -
    - - - - - Returns: -
      -
    • - the keys in the order given -
    • -
    - - - - - - - - Usage: -
    local key_three, key_one = extract({key_one='foo',key_two='bar',key_three=true},'key_three','key_one')
    - - -
    -
    -
    -
    - # - enum(tbl) -
    -
    -
    -
    - -

    Converts a table to an enum

    -

    - - - Parameters: - -
      - - - - - -
    • - - tbl - - : - - (table) - - table the that will be converted - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new table that acts like an enum -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - auto_complete(options, input[, use_key=false][, rtn_key=false]) -
    -
    -
    -
    - -

    Returns the closest match to the input

    -

    - - - Parameters: - -
      - - - - - -
    • - - options - - : - - (table) - - table a of options for the auto complete - -
    • - - - - - -
    • - - input - - : - - (string) - - string the input that will be completed - -
    • - - - - - -
    • - - use_key - - : - - (boolean) - - when true the keys of options will be used as the options - - (default: false) -
    • - - - - - -
    • - - rtn_key - - : - - (boolean) - - when true the the key will be returned rather than the value - - (default: false) -
    • - - -
    - - - - - Returns: -
      -
    • - the list item found that matches the input -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - table_values(tbl[, sorted][, as_string]) -
    -
    -
    -
    - -

    Returns a copy of all of the values in the table.

    -

    - - - Parameters: - -
      - - - - - -
    • - - tbl - - : - - (table) - - the 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 -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - table_keys(tbl[, sorted][, as_string]) -
    -
    -
    -
    - -

    Returns a copy of all of the keys in the table.

    -

    - - - Parameters: - -
      - - - - - -
    • - - tbl - - : - - (table) - - the 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 -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - 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 -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - table_keysort(tbl) -
    -
    -
    -
    - -

    Returns the list is a sorted way that would be expected by people (this is by key) (faster alternative than above)

    -

    - - - Parameters: - -
      - - - - - -
    • - - tbl - - : - - (table) - - the table to be sorted - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the sorted table -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - format_chat_colour(message, color) -
    -
    -
    -
    - -

    Returns a message with valid chat tags to change its colour

    -

    - - - Parameters: - -
      - - - - - -
    • - - message - - : - - (string) - - the message that will be in the output - -
    • - - - - - -
    • - - color - - : - - (table) - - a color which contains r,g,b as its keys - -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the message with the color tags included -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - format_chat_colour_localized(message, color) -
    -
    -
    -
    - -

    Returns a message with valid chat tags to change its colour, using localization

    -

    - - - Parameters: - -
      - - - - - -
    • - - message - - : - - (string or table) - - the message that will be in the output - -
    • - - - - - -
    • - - color - - : - - (table) - - a color which contains r,g,b as its keys - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the message with the color tags included -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - format_chat_player_name(player[, raw_string=false]) -
    -
    -
    -
    - -

    Returns the players name in the players color

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player to use the name and color of - -
    • - - - - - -
    • - - raw_string - - : - - (boolean) - - when true a is returned rather than a localized string - - (default: false) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the players name with tags for the players color -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - get_file_path([offset=0]) -
    -
    -
    -
    - -

    Returns a desync safe file path for the current file

    -

    - - - Parameters: - -
      - - - - - -
    • - - offset - - : - - (number) - - the offset in the stack to get, 0 is current file - - (default: 0) -
    • - - -
    - - - - - Returns: -
      -
    • - (string) - the file path -
    • -
    - - - - - - - - - -
    -
    -
    -
    - # - array_insert(tbl[, start_index], values) -
    -
    -
    -
    - -

    Much faster method for inserting items into an array

    -

    - - - Parameters: - -
      - - - - - -
    • - - tbl - - : - - (table) - - the table that will have the values added to it - -
    • - - - - - -
    • - - start_index - - : - - (number) - - the index at which values will be added, nil means end of the array - - (optional) -
    • - - - - - -
    • - - values - - : - - (table) - - the new values that will be added to the table - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the table that was passed as the first argument -
    • -
    - - - - - - - - Usage: -
    -- Adding 1000 values into the middle of the array
    -local tbl = {}
    -local values = {}
    -for i = 1,1000 do tbl[i] = i values[i] = i end
    -Common.array_insert(tbl,500,values) -- around 0.4ms
    - - -
    -
    -
    -
    - # - table_insert(tbl[, start_index], tbl2) -
    -
    -
    -
    - -

    Much faster method for inserting keys into a table

    -

    - - - Parameters: - -
      - - - - - -
    • - - tbl - - : - - (table) - - the table that will have keys added to it - -
    • - - - - - -
    • - - start_index - - : - - (number) - - the index at which values will be added, nil means end of the array, numbered indexs only - - (optional) -
    • - - - - - -
    • - - tbl2 - - : - - (table) - - the table that may contain both string and numbered keys - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the table passed as the first argument -
    • -
    - - - - - - - - Usage: -
    -- Merging two tables
    -local tbl = {}
    -local tbl2 = {}
    -for i = 1,100 do tbl[i] = i tbl['_'..i] = i tbl2[i] = i tbl2['__'..i] = i end
    -Common.table_insert(tbl,50,tbl2)
    - - -
    -
    -
    -
    - # - resolve_value(value) -
    -
    -
    -
    - -

    Used to resolve a value that could also be a function returning that value

    -

    - - - Parameters: - -
      - - - - - -
    • - - value - - : - - (any) - - the value which you want to test is not nil and if it is a function then call the function - -
    • - - -
    - - - - - Returns: -
      -
    • - (any) - the value given or returned by value if it is a function -
    • -
    - - - - - - - - Usage: -
    -- Default value handling
    --- if default value is not a function then it is returned
    --- if it is a function then it is called with the first argument being self
    -local value = Common.resolve_value(self.defaut_value,self)
    - -
    @@ -2746,7 +2820,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Common.html b/docs/core/Common.html new file mode 100644 index 00000000..2adc2dbf --- /dev/null +++ b/docs/core/Common.html @@ -0,0 +1,2759 @@ + + + + + + + + Common core + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    Common core

    +

    Core Module - Common +- Adds some commonly used functions used in many modules

    +

    + + + + + + + + + + + + + +

    Dependencies

    + + + + + + + + + + + + + +
    utils.color_presets
    utils.game
    util
    + + +

    Type Checking

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    type_check(value[, test_type=nil])Asserts the argument is of type test_type
    type_error(value, test_type, error_message, level)Raises an error if the value is of the wrong type
    multi_type_check(value, test_types)Asserts the argument is one of type test_types
    multi_type_error(value, test_types, error_message, level)Raises an error if the value is of the wrong type
    validate_argument_type(value, test_type, param_number[, param_name])Raises an error when the value is the incorrect type, uses a consistent error message format
    validate_argument_multi_type(value, test_types, param_number[, param_name])Raises an error when the value is the incorrect type, uses a consistent error message format
    error_if_runtime()Will raise an error if called during runtime
    error_if_runetime_closure(func)Will raise an error if the function is a closure
    + + +

    Value Returns

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    string_contains(s, contains)Tests if a string contains a given substring.
    resolve_value(value)Used to resolve a value that could also be a function returning that value
    cast_bool(var)Converts a varible into its boolean value, nil and false return false
    ternary(c, t, f)Returns either the second or third argument based on the first argument
    comma_value(n)Returns a string for a number with comma seperators
    set_and_return(tbl, key, value)Sets a table element to value while also returning value.
    write_json(path, tbl)Writes a table object to a file in json format
    opt_require(path)Calls a require that will not error if the file is not found
    get_file_path([offset=0])Returns a desync safe file path for the current file
    enum(tbl)Converts a table to an enum
    auto_complete(options, input[, use_key=false][, rtn_key=false])Returns the closest match to the input
    + + +

    Formating

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    get_actor(player_name)Returns a valid string with the name of the actor of a command.
    format_chat_colour(message, color)Returns a message with valid chat tags to change its colour
    format_chat_colour_localized(message, color)Returns a message with valid chat tags to change its colour, using localization
    format_chat_player_name(player[, raw_string=false])Returns the players name in the players color
    player_return(value[, 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
    format_time(ticks, options)Formats tick into a clean format, denominations from highest to lowest +-- time will use : separates +-- when a denomination is false it will overflow into the next one
    + + +

    Factorio

    + + + + + + + + + + + + + + + + +
    move_items(items[, surface=navies][, position={0][, radius=32][, chest_type=iron-chest])Moves items to the position and stores them in the closest entity of the type given
    print_grid_value(value, surface, position[, scale=1][, offset=0][, immutable=false])Prints a colored value on a location, color is based on the value.
    clear_flying_text(surface)Clears all flying text entities on a surface
    + + +
    + + +

    Dependencies

    +
    +
    +
    +
    + # + utils.color_presets +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.game +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + util +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +

    Type Checking

    +
    +
    +
    +
    + # + type_check(value[, test_type=nil]) +
    +
    +
    +
    + +

    Asserts the argument is of type test_type

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (any) + + the value to be tested + +
    • + + + + + +
    • + + test_type + + : + + (string) + + the type to test for if not given then it tests for nil + + (default: nil) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + is v of type test_type +
    • +
    + + + + + + + + Usage: +
    -- Check for a string value
    +local is_string = type_check(value, 'string')
    +
    -- Check for a nil value
    +local is_nil = type_check(value)
    + + +
    +
    +
    +
    + # + type_error(value, test_type, error_message, level) +
    +
    +
    +
    + +

    Raises an error if the value is of the wrong type

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (any) + + the value that you want to test the type of + +
    • + + + + + +
    • + + test_type + + : + + (string) + + the type that the value should be + +
    • + + + + + +
    • + + error_message + + : + + (string) + + the error message that is returned + +
    • + + + + + +
    • + + level + + : + + (number) + + the level to call the error on (level = 1 is the caller) + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if no error was called +
    • +
    + + + + + + + + Usage: +
    -- Raise error if value is not a number
    +type_error(value, 'number', 'Value must be a number')
    + + +
    +
    +
    +
    + # + multi_type_check(value, test_types) +
    +
    +
    +
    + +

    Asserts the argument is one of type test_types

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + + the variable to check + +
    • + + + + + +
    • + + test_types + + : + + + the type as a table of strings + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if value is one of test_types +
    • +
    + + + + + + + + Usage: +
    -- Check for a string or table
    +local is_string_or_table = multi_type_check(value, {'string','table'})
    + + +
    +
    +
    +
    + # + multi_type_error(value, test_types, error_message, level) +
    +
    +
    +
    + +

    Raises an error if the value is of the wrong type

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (any) + + the value that you want to test the type of + +
    • + + + + + +
    • + + test_types + + : + + (table) + + the type as a table of strings + +
    • + + + + + +
    • + + error_message + + : + + (string) + + the error message that is returned + +
    • + + + + + +
    • + + level + + : + + (number) + + the level to call the error on (level = 1 is the caller) + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if no error was called +
    • +
    + + + + + + + + Usage: +
    -- Raise error if value is not a string or table
    +multi_type_error('foo', {'string','table'}, 'Value must be a string or table')
    + + +
    +
    +
    +
    + # + validate_argument_type(value, test_type, param_number[, param_name]) +
    +
    +
    +
    + +

    Raises an error when the value is the incorrect type, uses a consistent error message format

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (any) + + the value that you want to test the type of + +
    • + + + + + +
    • + + test_type + + : + + (string) + + the type that the value should be + +
    • + + + + + +
    • + + param_number + + : + + (number) + + the number param it is + +
    • + + + + + +
    • + + param_name + + : + + (string) + + the name of the param + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if no error was raised +
    • +
    + + + + + + + + Usage: +
    -- Output: "Bad argument #2 to "<anon>"; argument is of type string expected number"
    +validate_argument_type(value, 'number', 2)
    +
    -- Output: "Bad argument #2 to "<anon>"; "repeat_count" is of type string expected number"
    +validate_argument_type(value, 'number', 2, 'repeat_count')
    + + +
    +
    +
    +
    + # + validate_argument_multi_type(value, test_types, param_number[, param_name]) +
    +
    +
    +
    + +

    Raises an error when the value is the incorrect type, uses a consistent error message format

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (any) + + the value that you want to test the type of + +
    • + + + + + +
    • + + test_types + + : + + (string) + + the types that the value should be + +
    • + + + + + +
    • + + param_number + + : + + (number) + + the number param it is + +
    • + + + + + +
    • + + param_name + + : + + (string) + + the name of the param + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if no error was raised +
    • +
    + + + + + + + + Usage: +
    -- Output: "Bad argument #2 to "<anon>"; argument is of type number expected string or table"
    +validate_argument_type(value, {'string','table'}, 2)
    +
    -- Output: "Bad argument #2 to "<anon>"; "player" is of type number expected string or table"
    +validate_argument_type(value, {'string','table'}, 2, 'player')
    + + +
    +
    +
    +
    + # + error_if_runtime() +
    +
    +
    +
    + +

    Will raise an error if called during runtime

    +

    + + + + + + + + + + + + + Usage: +
    error_if_runtime()
    + + +
    +
    +
    +
    + # + error_if_runetime_closure(func) +
    +
    +
    +
    + +

    Will raise an error if the function is a closure

    +

    + + + Parameters: + +
      + + + + + +
    • + + func + + + + + +
    • + + +
    + + + + + + + + + + + + Usage: +
    error_if_runetime_closure(func)
    + + +
    +
    +

    Value Returns

    +
    +
    +
    +
    + # + 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 +
    • +
    + + + + + + + + Usage: +
    -- Test if a string contains a sub string
    +local found = string_contains(str, 'foo')
    + + +
    +
    +
    +
    + # + resolve_value(value) +
    +
    +
    +
    + +

    Used to resolve a value that could also be a function returning that value

    +

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (any) + + the value which you want to test is not nil and if it is a function then call the function + +
    • + + +
    + + + + + Returns: +
      +
    • + (any) + the value given or returned by value if it is a function +
    • +
    + + + + + + + + Usage: +
    -- Default value handling
    +-- if default value is not a function then it is returned
    +-- if default value is a function then it is called with the first argument being self
    +local value = Common.resolve_value(self.defaut_value, self)
    + + +
    +
    +
    +
    + # + cast_bool(var) +
    +
    +
    +
    + +

    Converts a varible into its boolean value, nil and false return false

    +

    + + + Parameters: + +
      + + + + + +
    • + + var + + + + + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the boolean form of the varible +
    • +
    + + + + + + + + Usage: +
    local bool = cast_bool(var)
    + + +
    +
    +
    +
    + # + ternary(c, t, f) +
    +
    +
    +
    + +

    Returns either the second or third argument based on the first argument

    +

    + + + Parameters: + +
      + + + + + +
    • + + c + + + + + +
    • + + + + + +
    • + + t + + + + + +
    • + + + + + +
    • + + f + + + + + +
    • + + +
    + + + + + + + + + + + + Usage: +
    ternary(input_string == 'test', 'Input is test', 'Input is not test')
    + + +
    +
    +
    +
    + # + comma_value(n) +
    +
    +
    +
    + +

    Returns a string for a number with comma seperators

    +

    + + + Parameters: + +
      + + + + + +
    • + + n + + : + + (credit http) + + //richard.warburton.it + +
    • + + +
    + + + + + + + + + + + + Usage: +
    comma_value(input_number)
    + + +
    +
    +
    +
    + # + set_and_return(tbl, key, value) +
    +
    +
    +
    + +

    Sets a table element to value while also returning value.

    +

    + + + Parameters: + +
      + + + + + +
    • + + tbl + + : + + (table) + + to change the element of + +
    • + + + + + +
    • + + key + + : + + (string) + + the key to set the value of + +
    • + + + + + +
    • + + value + + : + + (any) + + the value to set the key as + +
    • + + +
    + + + + + Returns: +
      +
    • + (any) + the value that was set +
    • +
    + + + + + + + + Usage: +
    -- Set and return value
    +local value = set_and_return(players, player.name, player.online_time)
    + + +
    +
    +
    +
    + # + write_json(path, tbl) +
    +
    +
    +
    + +

    Writes a table object to a file in json format

    +

    + + + Parameters: + +
      + + + + + +
    • + + path + + : + + (string) + + the path of the file to write include / to use dir + +
    • + + + + + +
    • + + tbl + + : + + (table) + + the table that will be converted to a json string and wrote to file + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Write a lua table as a json to script-outpt/dump
    +write_json('dump', tbl)
    + + +
    +
    +
    +
    + # + opt_require(path) +
    +
    +
    +
    + +

    Calls a require that will not error if the file is not found

    +

    + + + Parameters: + +
      + + + + + +
    • + + path + + : + + (string) + + the path that you want to require + +
    • + + +
    + + + + + Returns: +
      +
    • + the returns from that file or nil, error if not loaded +
    • +
    + + + + + + + + Usage: +
    local file = opt_require('file.not.present') -- will not cause any error
    +
    -- Require a file without causing errors, for when a file might not exist
    +local Module = opt_require 'expcore.common'
    + + +
    +
    +
    +
    + # + get_file_path([offset=0]) +
    +
    +
    +
    + +

    Returns a desync safe file path for the current file

    +

    + + + Parameters: + +
      + + + + + +
    • + + offset + + : + + (number) + + the offset in the stack to get, 0 is current file + + (default: 0) +
    • + + +
    + + + + + Returns: +
      +
    • + (string) + the file path +
    • +
    + + + + + + + + Usage: +
    -- Get the current file path
    +local file_path = get_file_path()
    + + +
    +
    +
    +
    + # + enum(tbl) +
    +
    +
    +
    + +

    Converts a table to an enum

    +

    + + + Parameters: + +
      + + + + + +
    • + + tbl + + : + + (table) + + table the that will be converted + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the new table that acts like an enum +
    • +
    + + + + + + + + Usage: +
    -- Make an enum
    +local colors = enum{
    +    'red',
    +    'green',
    +    'blue'
    +}
    + + +
    +
    +
    +
    + # + auto_complete(options, input[, use_key=false][, rtn_key=false]) +
    +
    +
    +
    + +

    Returns the closest match to the input

    +

    + + + Parameters: + +
      + + + + + +
    • + + options + + : + + (table) + + table a of options for the auto complete + +
    • + + + + + +
    • + + input + + : + + (string) + + string the input that will be completed + +
    • + + + + + +
    • + + use_key + + : + + (boolean) + + when true the keys of options will be used as the options + + (default: false) +
    • + + + + + +
    • + + rtn_key + + : + + (boolean) + + when true the the key will be returned rather than the value + + (default: false) +
    • + + +
    + + + + + Returns: +
      +
    • + the list item found that matches the input +
    • +
    + + + + + + + + Usage: +
    -- Get the element that includes "foo"
    +local value = auto_complete(tbl, "foo")
    +
    -- Get the element with a key that includes "foo"
    +local value = auto_complete(tbl, "foo", true)
    +
    -- Get the key with that includes "foo"
    +local key = auto_complete(tbl, "foo", true, true)
    + + +
    +
    +

    Formating

    +
    +
    +
    +
    + # + get_actor(player_name) +
    +
    +
    +
    + +

    Returns a valid string with the name of the actor of a command.

    +

    + + + Parameters: + +
      + + + + + +
    • + + player_name + + : + + (string) + + the name of the player to use rather than server, used only if game.player is nil + +
    • + + +
    + + + + + Returns: +
      +
    • + (string) + the name of the current actor +
    • +
    + + + + + + + + Usage: +
    -- Get the current actor
    +local player_name = get_actor()
    + + +
    +
    +
    +
    + # + format_chat_colour(message, color) +
    +
    +
    +
    + +

    Returns a message with valid chat tags to change its colour

    +

    + + + Parameters: + +
      + + + + + +
    • + + message + + : + + (string) + + the message that will be in the output + +
    • + + + + + +
    • + + color + + : + + (table) + + a color which contains r,g,b as its keys + +
    • + + +
    + + + + + Returns: +
      +
    • + (string) + the message with the color tags included +
    • +
    + + + + + + + + Usage: +
    -- Use factorio tags to color a chat message
    +local message = format_chat_colour('Hello, World!', { r=355, g=100, b=100 })
    + + +
    +
    +
    +
    + # + format_chat_colour_localized(message, color) +
    +
    +
    +
    + +

    Returns a message with valid chat tags to change its colour, using localization

    +

    + + + Parameters: + +
      + + + + + +
    • + + message + + : + + (string or table) + + the message that will be in the output + +
    • + + + + + +
    • + + color + + : + + (table) + + a color which contains r,g,b as its keys + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the message with the color tags included +
    • +
    + + + + + + + + Usage: +
    -- Use factorio tags and locale strings to color a chat message
    +local message = format_chat_colour_localized('Hello, World!', { r=355, g=100, b=100 })
    + + +
    +
    +
    +
    + # + format_chat_player_name(player[, raw_string=false]) +
    +
    +
    +
    + +

    Returns the players name in the players color

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player to use the name and color of + +
    • + + + + + +
    • + + raw_string + + : + + (boolean) + + when true a string is returned rather than a localized string + + (default: false) +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the players name with tags for the players color +
    • +
    + + + + + + + + Usage: +
    -- Format a players name using the players color as a string
    +local message = format_chat_player_name(game.player, true)
    + + +
    +
    +
    +
    + # + player_return(value[, 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: + +
      + + + + + +
    • + + value + + : + + (any) + + a 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, ignored 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: +
    -- Return a value to the current actor, rcon included
    +player_return('Hello, World!')
    +
    -- Return a value to the current actor, with color
    +player_return('Hello, World!', 'green')
    +
    -- Return to a player other than the current
    +player_return('Hello, World!', nil, player)
    + + +
    +
    +
    +
    + # + format_time(ticks, options) +
    +
    +
    +
    + +

    Formats tick into a clean format, denominations from highest to lowest +-- time will use : separates +-- when a denomination is false it will overflow into the next one

    +

    + + + Parameters: + +
      + + + + + +
    • + + ticks + + : + + (number) + + the number of ticks that represents a time + +
    • + + + + + +
    • + + options + + : + + (table) + + table a of options to use for the format + +
    • + + +
    + + + + + Returns: +
      +
    • + (string) + a locale string that can be used +
    • +
    + + + + + + + + Usage: +
    -- Output: "0h 5m"
    +local time = format_time(18000, { hours=true, minutes=true, string=true })
    +
    -- Output: "0 hours and 5 minutes"
    +local time = format_time(18000, { hours=true, minutes=true, string=true, long=true })
    +
    -- Output: "00:05:00"
    +local time = format_time(18000, { hours=true, minutes=true, seconds=true, string=true })
    +
    -- Output: "--:--:--"
    +local time = format_time(18000, { hours=true, minutes=true, seconds=true, string=true, null=true })
    + + +
    +
    +

    Factorio

    +
    +
    +
    +
    + # + move_items(items[, surface=navies][, position={0][, radius=32][, chest_type=iron-chest]) +
    +
    +
    +
    + +

    Moves items to the position and stores them in the closest entity of the type given

    +

    + + + Parameters: + +
      + + + + + +
    • + + items + + : + + (table) + + items which are to be added to the chests, ['name']=count + +
    • + + + + + +
    • + + surface + + : + + (LuaSurface) + + the surface that the items will be moved to + + (default: navies) +
    • + + + + + +
    • + + position + + : + + (table) + + the position that the items will be moved to {x=100,y=100} + + (default: {0) +
    • + + + + + +
    • + + radius + + : + + (number) + + the radius in which the items are allowed to be placed + + (default: 32) +
    • + + + + + +
    • + + chest_type + + : + + (string) + + the chest type that the items should be moved into + + (default: iron-chest) +
    • + + +
    + + + + + Returns: +
      +
    • + (LuaEntity) + the last chest that had items inserted into it +
    • +
    + + + + + + + + Usage: +
    -- Copy all the items in a players inventory and place them in chests at {0,0}
    +move_items(game.player.get_main_inventory().get_contents())
    + + +
    +
    +
    +
    + # + print_grid_value(value, surface, position[, scale=1][, offset=0][, immutable=false]) +
    +
    +
    +
    + +

    Prints a colored value on a location, color is based on the value.

    +

    +nb: src is below but the gradent has been edited +https://github.com/Refactorio/RedMew/blob/9184b2940f311d8c9c891e83429fc57ec7e0c4a2/map_gen/maps/diggy/debug.lua#L31

    + + + Parameters: + +
      + + + + + +
    • + + value + + : + + (number) + + the value to show must be between -1 and 1, scale can be used to achive this + +
    • + + + + + +
    • + + surface + + : + + (LuaSurface) + + the surface to palce the value on + +
    • + + + + + +
    • + + position + + : + + (table) + + {x, y} the possition to palce the value at + +
    • + + + + + +
    • + + scale + + : + + (number) + + how much to scale the colours by + + (default: 1) +
    • + + + + + +
    • + + offset + + : + + (number) + + the offset in the +x +y direction + + (default: 0) +
    • + + + + + +
    • + + immutable + + : + + (boolean) + + if immutable, only set, never do a surface lookup, values never change + + (default: false) +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Place a 0 at {0,0}
    +print_grid_value(0, game.player.surface, { x=0, y=0 })
    + + +
    +
    +
    +
    + # + clear_flying_text(surface) +
    +
    +
    +
    + +

    Clears all flying text entities on a surface

    +

    + + + Parameters: + +
      + + + + + +
    • + + surface + + : + + (LuaSurface) + + the surface to clear + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Remove all flying text on the surface
    +clear_flying_text(game.player.surface)
    + + +
    +
    + + + +
    +
    +
    + + + + diff --git a/docs/core/Groups.html b/docs/core/Groups.html new file mode 100644 index 00000000..fcf6fcc9 --- /dev/null +++ b/docs/core/Groups.html @@ -0,0 +1,1435 @@ + + + + + + + + Groups core + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    Groups core

    +

    Core Module - Permission Groups +- Permission group making for factorio so you never have to make one by hand again

    +

    + + + + + + +

    Usage

    +
    --- Example Group (Allow All)
    +-- here we will create an admin group however we do not want them to use the map editor or mess with the permission groups
    +Permission_Groups.new_group('Admin') -- this defines a new group called "Admin"
    +:allow_all() -- this makes the default to allow any input action unless set other wise
    +:disallow{ -- here we disallow the input action we don't want them to use
    +    'add_permission_group',
    +    'delete_permission_group',
    +    'import_permissions_string',
    +    'map_editor_action',
    +    'toggle_map_editor'
    +}
    +
    --- Example Group (Disallow All)
    +-- here we will create a group that cant do anything but talk in chat
    +Permission_Groups.new_group('Restricted') -- this defines a new group called "Restricted"
    +:disallow_all() -- this makes the default to disallow any input action unless set other wise
    +:allow('write_to_console') -- here we allow them to chat, {} can be used here if we had more than one action
    +
    + + + + + + + +

    Dependencies

    + + + + + + + + + + + + + +
    utils.game
    utils.event
    expcore.async
    + + +

    Getters

    + + + + + + + + + + + + + + + + +
    new_group(name)Defines a new permission group that can have it actions set in the config
    get_group_by_name(name)Returns the group with the given name, case sensitive
    get_group_from_player(player)Returns the group that a player is in
    + + +

    Setters

    + + + + + + + + + + + + +
    reload_permissions()Reloads/creates all permission groups and sets them to they configured state
    set_player_group(player, group)Sets a player's group to the one given, a player can only have one group at a time
    + + +

    Actions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Permissions_Groups._prototype:set_action(action, state)Sets the allow state of an action for this group, used internally but is safe to use else where
    Permissions_Groups._prototype:allow(actions)Sets an action or actions to be allowed for this group even with disallow_all triggered, Do not use in runtime
    Permissions_Groups._prototype:disallow(actions)Sets an action or actions to be disallowed for this group even with allow_all triggered, Do not use in runtime
    Permissions_Groups._prototype:allow_all()Sets the default state for any actions not given to be allowed, useful with :disallow
    Permissions_Groups._prototype:disallow_all()Sets the default state for any action not given to be disallowed, useful with :allow
    Permissions_Groups._prototype:is_allowed(action)Returns if an input action is allowed for this group
    + + +

    Players

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Permissions_Groups._prototype:create()Creates or updates the permission group with the configured actions, used internally
    Permissions_Groups._prototype:get_raw()Returns the LuaPermissionGroup that was created with this group object, used internally
    Permissions_Groups._prototype:add_player(player)Adds a player to this group
    Permissions_Groups._prototype:remove_player(player)Removes a player from this group
    Permissions_Groups._prototype:get_players([online])Returns all player that are in this group with the option to filter to online/offline only
    Permissions_Groups._prototype:print(message)Prints a message to every player in this group
    + + +
    + + +

    Dependencies

    +
    +
    +
    +
    + # + utils.game +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.event +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + expcore.async +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +

    Getters

    +
    +
    +
    +
    + # + new_group(name) +
    +
    +
    +
    + +

    Defines a new permission group that can have it actions set in the config

    +

    + + + Parameters: + +
      + + + + + +
    • + + name + + : + + (string) + + the name of the new group + +
    • + + +
    + + + + + Returns: +
      +
    • + (Permissions_Groups._prototype) + the new group made with function to allow and disallow actions +
    • +
    + + + + + + + + Usage: +
    -- Defining a new permission group
    +Groups.new_group('Admin')
    + + +
    +
    +
    +
    + # + get_group_by_name(name) +
    +
    +
    +
    + +

    Returns the group with the given name, case sensitive

    +

    + + + Parameters: + +
      + + + + + +
    • + + name + + : + + (string) + + the name of the group to get + +
    • + + +
    + + + + + Returns: +
      +
    • + (Permissions_Groups._prototype or nil) + the group with that name or nil if non found +
    • +
    + + + + + + + + Usage: +
    -- Getting a permision group
    +local admin_group = Groups.get_group_by_name('Admin')
    + + +
    +
    +
    +
    + # + get_group_from_player(player) +
    +
    +
    +
    + +

    Returns the group that a player is in

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player to get the group of can be name index etc + +
    • + + +
    + + + + + Returns: +
      +
    • + (Permissions_Groups._prototype or nil) + the group with that player or nil if non found +
    • +
    + + + + + + + + Usage: +
    -- Get your permission group
    +local group = Groups.get_group_from_player(game.player)
    + + +
    +
    +

    Setters

    +
    +
    +
    +
    + # + reload_permissions() +
    +
    +
    +
    + +

    Reloads/creates all permission groups and sets them to they configured state

    +

    + + + + + + + + + + + + + Usage: +
    -- Reload the permission groups, used internally
    +Groups.reload_permissions()
    + + +
    +
    +
    +
    + # + set_player_group(player, group) +
    +
    +
    +
    + +

    Sets a player's group to the one given, a player can only have one group at a time

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player to effect can be name index etc + +
    • + + + + + +
    • + + group + + : + + (string) + + the name of the group to give to the player + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if the player was added successfully, false other wise +
    • +
    + + + + + + + + Usage: +
    -- Set your permission group
    +Groups.set_player_group(game.player, 'Admin')
    + + +
    +
    +

    Actions

    +
    +
    +
    +
    + # + Permissions_Groups._prototype:set_action(action, state) +
    +
    +
    +
    + +

    Sets the allow state of an action for this group, used internally but is safe to use else where

    +

    + + + Parameters: + +
      + + + + + +
    • + + action + + : + + (string or defines.input_action) + + the action that you want to set the state of + +
    • + + + + + +
    • + + state + + : + + (boolean) + + the state that you want to set it to, true = allow, false = disallow + +
    • + + +
    + + + + + Returns: +
      +
    • + (Permissions_Groups._prototype) + returns self so function can be chained +
    • +
    + + + + + + + + Usage: +
    -- Set an action to be disalowed
    +group:set_action('toggle_map_editor', false)
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:allow(actions) +
    +
    +
    +
    + +

    Sets an action or actions to be allowed for this group even with disallow_all triggered, Do not use in runtime

    +

    + + + Parameters: + +
      + + + + + +
    • + + actions + + : + + (string or Array) + + the action or actions that you want to allow for this group + +
    • + + +
    + + + + + Returns: +
      +
    • + (Permissions_Groups._prototype) + returns self so function can be chained +
    • +
    + + + + + + + + Usage: +
    -- Allow some actions
    +group:allow{
    +    'write_to_console'
    +}
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:disallow(actions) +
    +
    +
    +
    + +

    Sets an action or actions to be disallowed for this group even with allow_all triggered, Do not use in runtime

    +

    + + + Parameters: + +
      + + + + + +
    • + + actions + + : + + (string or Array) + + the action or actions that you want to disallow for this group + +
    • + + +
    + + + + + Returns: +
      +
    • + (Permissions_Groups._prototype) + returns self so function can be chained +
    • +
    + + + + + + + + Usage: +
    -- Disalow some actions
    +group:disallow{
    +    'add_permission_group',
    +    'delete_permission_group',
    +    'import_permissions_string',
    +    'map_editor_action',
    +    'toggle_map_editor'
    +}
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:allow_all() +
    +
    +
    +
    + +

    Sets the default state for any actions not given to be allowed, useful with :disallow

    +

    + + + + + + Returns: +
      +
    • + (Permissions_Groups._prototype) + returns self so function can be chained +
    • +
    + + + + + + + + Usage: +
    -- Allow all actions unless given by disallow
    +group:allow_all()
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:disallow_all() +
    +
    +
    +
    + +

    Sets the default state for any action not given to be disallowed, useful with :allow

    +

    + + + + + + Returns: +
      +
    • + (Permissions_Groups._prototype) + returns self so function can be chained +
    • +
    + + + + + + + + Usage: +
    -- Disallow all actions unless given by allow
    +group:disallow_all()
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:is_allowed(action) +
    +
    +
    +
    + +

    Returns if an input action is allowed for this group

    +

    + + + Parameters: + + + + + + + Returns: +
      +
    • + (boolean) + true if the group is allowed the action, false other wise +
    • +
    + + + + + + + + Usage: +
    -- Test if a group is allowed an action
    +local allowed = group:is_allowed('write_to_console')
    + + +
    +
    +

    Players

    +
    +
    +
    +
    + # + Permissions_Groups._prototype:create() +
    +
    +
    +
    + +

    Creates or updates the permission group with the configured actions, used internally

    +

    + + + + + + Returns: + + + + + + + + + Usage: +
    -- Create the permission group so players can be added, used internally
    +group:create()
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:get_raw() +
    +
    +
    +
    + +

    Returns the LuaPermissionGroup that was created with this group object, used internally

    +

    + + + + + + Returns: + + + + + + + + + Usage: +
    -- Get the factorio api permision group, used internally
    +local permission_group = group:get_raw()
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:add_player(player) +
    +
    +
    +
    + +

    Adds a player to this group

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + LuaPlayer the player you want to add to this group can be name or index etc + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if the player was added successfully, false other wise +
    • +
    + + + + + + + + Usage: +
    -- Add a player to this permission group
    +group:add_player(game.player)
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:remove_player(player) +
    +
    +
    +
    + +

    Removes a player from this group

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + LuaPlayer the player you want to remove from this group can be name or index etc + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if the player was removed successfully, false other wise +
    • +
    + + + + + + + + Usage: +
    -- Remove a player from this permission group
    +group:remove_player(game.player)
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:get_players([online]) +
    +
    +
    +
    + +

    Returns all player that are in this group with the option to filter to online/offline only

    +

    + + + Parameters: + +
      + + + + + +
    • + + online + + : + + (boolean) + + if nil returns all players, if true online players only, if false returns online players only + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + a table of players that are in this group; filtered if online param is given +
    • +
    + + + + + + + + Usage: +
    -- Get all players in this group
    +local online_players = group:get_players()
    +
    -- Get all online players in this group
    +local online_players = group:get_players(true)
    + + +
    +
    +
    +
    + # + Permissions_Groups._prototype:print(message) +
    +
    +
    +
    + +

    Prints a message to every player in this group

    +

    + + + Parameters: + +
      + + + + + +
    • + + message + + : + + (string) + + the message that you want to send to the players + +
    • + + +
    + + + + + Returns: +
      +
    • + (number) + the number of players that received the message +
    • +
    + + + + + + + + Usage: +
    -- Print a message to all players in thie group
    +group:print('Hello, World!')
    + + +
    +
    + + + +
    +
    +
    + + + + diff --git a/docs/core/Gui.html b/docs/core/Gui.html index 72fc7784..e9480d3c 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -44,11 +44,13 @@ + + + + - - @@ -56,13 +58,13 @@ @@ -91,10 +93,12 @@ + + @@ -103,8 +107,10 @@

    Guis

    @@ -142,7 +148,6 @@

    Configs

    @@ -175,18 +181,13 @@

    Modules

    @@ -211,11 +212,13 @@ + + + + - - @@ -236,7 +239,7 @@

    Gui core

    Core Module - Gui -- Used to define new gui elements and gui event handlers

    +- Used to simplify gui creation using factory functions called element defines

    @@ -245,65 +248,114 @@

    Usage

    -
    -- Defining a button that prints the player's name
    +    
    -- To draw your element you only need to call the factory function
    +-- You are able to pass any other arguments that are used in your custom functions but the first is always the parent element
    +local example_button_element = example_button(parent_element)
    +
    -- Making a factory function for a button with the caption "Example Button"
    +-- This method has all the same features as LuaGuiElement.add
     local example_button =
     Gui.element{
         type = 'button',
         caption = 'Example Button'
    -}
    -:on_click(function(player,element,event)
    -    player.print(player.name)
    -end)
    -
    -- Defining a button with a custom style
    -local example_button =
    -Gui.element{
    -    type = 'button',
    -    caption = 'Example Button'
    -}
    -:style{
    -    height = 25,
    -    width = 100
    -}
    -:on_click(function(player,element,event)
    -    player.print(player.name)
    -end)
    -
    -- Defining a button using a custom function
    +}
    +
    -- Making a factory function for a button which is contained within a flow
    +-- This method is for when you still want to register event handlers but cant use the table method
     local example_flow_with_button =
    -Gui.element(function(event_trigger,parent)
    -    -- Add the flow the button is in
    +Gui.element(function(event_trigger,parent,...)
    +    -- ... shows that all other arguments from the factory call are passed to this function
    +    -- Here we are adding a flow which we will then later add a button to
         local flow =
    -    parent.add{
    -        name = 'example_flow',
    +    parent.add{ -- paraent is the element which is passed to the factory function
    +        name = 'example_flow',
             type = 'flow'
         }
     
    -    -- Get the players name
    -    local player = game.players[parent.player_index]
    -    local player_name = player.name
    -
    -    -- Add the button
    +    -- Now we add the button to the flow that we created earlier
         local element =
         flow.add{
    -        name = event_trigger,
    -        type = 'button',
    -        caption = 'Example Button: '..player_name
    +        name = event_trigger, -- event_trigger should be the name of any elements you want to trigger your event handlers
    +        type = 'button',
    +        caption = 'Example Button'
         }
     
    -    -- Set the style of the button
    -    local style = element.style
    -    style.height = 25
    -    style.width = 100]
    -    style.font_color = player.color
    -
    -    -- Return the element
    +    -- You must return a new element, this is so styles can be applied and returned to the caller
    +    -- You may return any of your elements that you added, consider the context in which it will be used for which should be returned
         return element
    -end)
    -:on_click(function(player,element,event)
    -    player.print(player.name)
     end)
    -
    -- Drawing an element
    -local exmple_button_element = example_button(parent)
    -local example_flow_with_button = example_flow_with_button(parent)
    +
    -- Styles can be added to any element define, simplest way mimics LuaGuiElement.style[key] = value
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button',
    +    style = 'forward_button' -- factorio styles can be applied here
    +}
    +:style{
    +    height = 25, -- same as element.style.height = 25
    +    width = 100 -- same as element.style.width = 25
    +}
    +
    -- Styles can also have a custom function when the style is dynamic and depends on other factors
    +-- Use this method if your style is dynamic and depends on other factors
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button',
    +    style = 'forward_button' -- factorio styles can be applied here
    +}
    +:style(function(style,element,...)
    +    -- style is the current style object for the elemenent
    +    -- element is the element that is being changed
    +    -- ... shows that all other arguments from the factory call are passed to this function
    +    local player = game.players[element.player_index]
    +    style.height = 25
    +    style.width = 100
    +    style.font_color = player.color
    +end)
    +
    -- You are able to register event handlers to your elements, these can be factorio events or custom ones
    +-- All events are checked to be valid before raising any handlers, this means element.valid = true and player.valid = true
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button'
    +}
    +:on_click(function(player,element,event)
    +    -- player is the player who interacted with the element to cause the event
    +    -- element is a refrence to the element which caused the event
    +    -- event is a raw refrence to the event data if player and element are not enough
    +    player.print('Clicked: '..element.name)
    +end)
    +
    -- Example from core_defines, Gui.core_defines.hide_left_flow, called like: hide_left_flow(parent_element)
    +--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible
    +-- @element hide_left_flow
    +local hide_left_flow =
    +Gui.element{
    +    type = 'sprite-button',
    +    sprite = 'utility/close_black',
    +    style = 'tool_button',
    +    tooltip = {'expcore-gui.left-button-tooltip'}
    +}
    +:style{
    +    padding = -3,
    +    width = 18,
    +    height = 20
    +}
    +:on_click(function(player,_,_)
    +    Gui.hide_left_flow(player)
    +end)
    +
    -- Eample from defines, Gui.alignment, called like: Gui.alignment(parent, name, horizontal_align, vertical_align)
    +-- Notice how _ are used to blank arguments that are not needed in that context and how they line up with above
    +Gui.alignment =
    +Gui.element(function(_,parent,name,_,_)
    +    return parent.add{
    +        name = name or 'alignment',
    +        type = 'flow',
    +    }
    +end)
    +:style(function(style,_,_,horizontal_align,vertical_align)
    +    style.padding = {1,2}
    +    style.vertical_align = vertical_align or 'center'
    +    style.horizontal_align = horizontal_align or 'right'
    +    style.vertically_stretchable  = style.vertical_align ~= 'center'
    +    style.horizontally_stretchable = style.horizontal_align ~= 'center'
    +end)
    @@ -330,24 +382,28 @@ Gui.element(function(event_trigger,parent) - top_elements - Contains the uids of the elements that will show on the top flow and the auth function - - - left_elements - Contains the uids of the elements that will show on the left flow and the open on join function + events + String indexed table used to avoid conflict with custom event names, similar to how defines.events works defines - Table of all the elements which have been registed with the draw function and event handlers + Uid indexed array that stores all the factory functions that were defined, no new values will be added during runtime + + + core_defines + An string indexed table of all the defines which are used by the core of the gui system, used for internal refrence file_paths - An index used for debuging to find the file where different elements where registered + Used to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debuging + + + debug_info + Used to store extra infomation about elements as they get defined such as the params used and event handlers registered to them _prototype_element - The element prototype which is returned from Gui.element + The prototype used to store the functions of an element define _mt_element @@ -363,7 +419,139 @@ Gui.element(function(event_trigger,parent) uid - The current highest uid that is being used, will not increase during runtime + The current highest uid that is being used by a define, will not increase during runtime + + + + + +

    Core Defines

    + + + + + + + + + + + + + + + + +
    hide_top_flowButton which toggles the top flow elements, version which shows inside the top flow when top flow is visible
    show_top_flowButton which toggles the top flow elements, version which shows inside the left flow when top flow is hidden
    hide_left_flowButton which hides the elements in the left flow, shows inside the left flow when frames are visible
    + + +

    Defines

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    alignmentDraw a flow used to align its child elements, default is right align
    scroll_tableDraw a scroll pane that has a table inside of it
    headerUsed to add a frame with the header style, has the option for a right alignment flow for buttons
    footerUsed to add a frame with the footer style, has the option for a right alignment flow for buttons
    containerUsed for left frames to give them a nice boarder
    barUsed to make a solid white bar in a gui
    centered_labelUsed to make a label which is centered and of a certian size
    title_labelUsed to make a title which has two bars on either side
    + + +

    Helper Functions

    + + + + + + + + + + + + + + + + + + + + + + + + +
    get_player_from_element(element)Get the player that owns a gui element
    toggle_enabled_state(element[, state])Will toggle the enabled state of an element or set it to the one given
    toggle_visible_state(element[, state])Will toggle the visible state of an element or set it to the one given
    destroy_if_valid(element)Destory a gui element without causing any errors, often because the element was already removed
    sprite_style(size[, padding=-2][, style])Returns a table to be used as the style for a sprite buttons, produces a sqaure button
    + + +

    Left Flow

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    left_elementsContains the uids of the elements that will shown on the left flow and their join functions
    get_left_flow(player)Gets the flow refered to as the left flow, each player has one left flow
    Gui._prototype_element:add_to_left_flow([open_on_join])Sets an element define to be drawn to the left flow when a player joins, includes optional check
    left_toolbar_button(sprite, tooltip, element_define[, authenticator])Creates a button on the top flow which will toggle the given element define, the define must exist in the left flow
    draw_left_flow(player)Draw all the left elements onto the left flow, internal use only with on join
    update_left_flow(player)Update the visible state of the hide button, can be used to check if any frames are visible
    hide_left_flow(player)Hides all left elements for a player
    get_left_element(player, element_define)Get the element define that is in the left flow, use in events without an element refrence
    toggle_left_element(player, element_define[, state])Toggles the visible state of a left element for a given player, can be used to set the visible state
    @@ -375,19 +563,19 @@ Gui.element(function(event_trigger,parent) element(element_define) - Base function used to define new elements, can be used with a table or with a function + Used to define new elements for your gui, can be used like LuaGuiElement.add or a custom function Gui._prototype_element:style(style_define) - Extension of Gui.element when using the table method, values applied after the element is drawn + Used to extent your element define with a style factory, this style will be applied to your element when created, can also be a custom function - Gui._prototype_element:add_to_top_flow([authenticator]) - Adds an element to be drawn to the top flow when a player joins + Gui._prototype_element:on_custom_event(event_name, handler) + Set the handler which will be called for a custom event, only one handler can be used per event per element - Gui._prototype_element:add_to_left_flow([open_on_join]) - Adds an element to be drawn to the left flow when a player joins + Gui._prototype_element:raise_custom_event(event) + Raise the handler which is attached to an event; external use should be limited to custom events @@ -398,11 +586,11 @@ Gui.element(function(event_trigger,parent) - Gui._prototype_element.on_opened + Gui._prototype_element.on_open Called when the player opens a GUI. - Gui._prototype_element.on_closed + Gui._prototype_element.on_close Called when the player closes the GUI they have open. @@ -438,7 +626,7 @@ Gui.element(function(event_trigger,parent) Called when LuaGuiElement switch state is changed (related to switches). - Gui._prototype_element.on_text_change + Gui._prototype_element.on_text_changed Called when LuaGuiElement text is changed by the player. @@ -454,84 +642,44 @@ Gui.element(function(event_trigger,parent) - toggle_top_flow - Button which toggles the top flow elements + top_elements + Contains the uids of the elements that will shown on the top flow and their auth functions top_flow_button_style The style that should be used for buttons on the top flow + top_flow_button_visible_style + The style that should be used for buttons on the top flow when their flow is visible + + get_top_flow(player) - Gets the flow which contains the elements for the top flow + Gets the flow refered to as the top flow, each player has one top flow + + + Gui._prototype_element:add_to_top_flow([authenticator]) + Sets an element define to be drawn to the top flow when a player joins, includes optional authenticator update_top_flow(player) - Updates the visible states of all the elements on a players top flow + Updates the visible state of all the elements on the players top flow, uses authenticator toggle_top_flow(player[, state]) - Toggles the visible states of all the elements on a players top flow - - - - - -

    Left Flow

    - - - - - - + - - + + - - + + - - - - -
    hide_left_flowButton which hides the elements in the left flowToggles the visible state of all the elements on a players top flow, effects all elements
    get_left_flow(player)Gets the flow which contains the elements for the left flowget_top_element(player, element_define)Get the element define that is in the top flow, use in events without an element refrence
    hide_left_flow(player)Hides all left elements for a playertoolbar_button(sprite, tooltip[, authenticator])Creates a button on the top flow with consistent styling
    toggle_left_element(player, element_define[, state])Toggles the visible state of all a left element for a player
    - - -

    Helper Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
    get_player_from_element(element)Get the player that owns a gui element
    toggle_enabled_state(element[, state])Will toggle the enabled state of an element or set it to the one given
    toggle_visible_state(element[, state])Will toggle the visible state of an element or set it to the one given
    destroy_if_valid(element)Destory a gui element without causing any errors, likly if the element may have already been removed
    alignment(parent[, horizontal_align='right'][, vertical_align='center'][, name='alignment'])Draw a flow that has custom element alignments, default is right align
    scroll_table(parent, height, column_count[, name='scroll'])Draw a scroll pane that has a table inside of it
    header(parent, caption[, tooltip][, add_alignment=false][, name='header'])Used to add a header to a frame, this has the option for a custom right alignment flow for buttonstoolbar_button_style(button, state)Styles a top flow button depending on the state given
    @@ -598,41 +746,14 @@ Gui.element(function(event_trigger,parent)
    - # - top_elements + # + events
    -

    Contains the uids of the elements that will show on the top flow and the auth function

    -

    - - - - - - - - - - - - - - -
    -
    -
    -
    - # - left_elements -
    -
    -
    -
    - -

    Contains the uids of the elements that will show on the left flow and the open on join function

    +

    String indexed table used to avoid conflict with custom event names, similar to how defines.events works

    @@ -659,7 +780,34 @@ Gui.element(function(event_trigger,parent)
    -

    Table of all the elements which have been registed with the draw function and event handlers

    +

    Uid indexed array that stores all the factory functions that were defined, no new values will be added during runtime

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + core_defines +
    +
    +
    +
    + +

    An string indexed table of all the defines which are used by the core of the gui system, used for internal refrence

    @@ -686,7 +834,34 @@ Gui.element(function(event_trigger,parent)
    -

    An index used for debuging to find the file where different elements where registered

    +

    Used to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debuging

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + debug_info +
    +
    +
    +
    + +

    Used to store extra infomation about elements as they get defined such as the params used and event handlers registered to them

    @@ -713,7 +888,7 @@ Gui.element(function(event_trigger,parent)
    -

    The element prototype which is returned from Gui.element

    +

    The prototype used to store the functions of an element define

    @@ -791,30 +966,10 @@ Gui.element(function(event_trigger,parent)
    -

    The current highest uid that is being used, will not increase during runtime

    +

    The current highest uid that is being used by a define, will not increase during runtime

    - -
      - - - - - -
    • - - uid - - - - - -
    • - - -
    - @@ -829,908 +984,19 @@ Gui.element(function(event_trigger,parent)
    -

    Element Define

    +

    Core Defines

    - # - element(element_define) + # + hide_top_flow
    -

    Base function used to define new elements, can be used with a table or with a function

    -

    - - - Parameters: - -
      - - - - - -
    • - - element_define - - : - - (table or function) - - used to define how the element is draw, using a table is the simplist way of doing this - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new element define that is used to register events to this element -
    • -
    - - - - - - - - Usage: -
    -- Defining an element with a table
    -local example_button =
    -Gui.element{
    -    type = 'button',
    -    caption = 'Example Button'
    -}
    -
    -- Defining an element with a function
    -local example_flow_with_button =
    -Gui.element(function(event_trigger,parent,...)
    -    -- Add the flow the button is in
    -    local flow =
    -    parent.add{
    -        name = 'example_flow',
    -        type = 'flow'
    -    }
    -
    -    -- Add the button
    -    local element =
    -    flow.add{
    -        name = event_trigger,
    -        type = 'button',
    -        caption = 'Example Button'
    -    }
    -
    -    -- Set the style of the button
    -    local style = element.style
    -    style.height = 25
    -    style.width = 100
    -
    -    -- Return the element
    -    return element
    -end)
    - - -
    -
    -
    -
    - # - Gui._prototype_element:style(style_define) -
    -
    -
    -
    - -

    Extension of Gui.element when using the table method, values applied after the element is drawn

    -

    - - - Parameters: - -
      - - - - - -
    • - - style_define - - : - - (table or function) - - used to define how the style is applied, using a table is the simplist way of doing this - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new element define that is used to register events to this element -
    • -
    - - - - - - - - Usage: -
    -- Setting the height and width of the example button
    -local example_button =
    -Gui.element{
    -    type = 'button',
    -    caption = 'Example Button'
    -}
    -:style{
    -    height = 25,
    -    width = 100
    -}
    -
    -- Using a function to set the style
    -local example_button =
    -Gui.element{
    -    type = 'button',
    -    caption = 'Example Button'
    -}
    -:style(function(style,element,...)
    -    local player = game.players[element.player_index]
    -    style.height = 25
    -    style.width = 100
    -    style.font_color = player.color
    -end)
    - - -
    -
    -
    -
    - # - Gui._prototype_element:add_to_top_flow([authenticator]) -
    -
    -
    -
    - -

    Adds an element to be drawn to the top flow when a player joins

    -

    - - - Parameters: - -
      - - - - - -
    • - - authenticator - - : - - (function) - - called during toggle or update to decide if the element should be visible - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new element define that is used to register events to this element -
    • -
    - - - - - - - - Usage: -
    -- Adding the example button
    -example_button:add_to_top_flow(function(player)
    -    -- example button will only show when game time is less than 1 minute
    -    return player.online_time < 3600
    -end)
    - - -
    -
    -
    -
    - # - Gui._prototype_element:add_to_left_flow([open_on_join]) -
    -
    -
    -
    - -

    Adds an element to be drawn to the left flow when a player joins

    -

    - - - Parameters: - -
      - - - - - -
    • - - open_on_join - - : - - (boolean or function) - - called during first darw to decide if the element is visible - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - the new element define that is used to register events to this element -
    • -
    - - - - - - - - Usage: -
    -- Adding the example button
    -example_flow_with_button:add_to_left_flow(true)
    - - -
    -
    -

    Element Events

    -
    -
    -
    -
    - # - Gui._prototype_element.on_opened -
    -
    -
    -
    - -

    Called when the player opens a GUI.

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_closed -
    -
    -
    -
    - -

    Called when the player closes the GUI they have open.

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_click -
    -
    -
    -
    - -

    Called when LuaGuiElement is clicked.

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_confirmed -
    -
    -
    -
    - -

    Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_checked_changed -
    -
    -
    -
    - -

    Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_elem_changed -
    -
    -
    -
    - -

    Called when LuaGuiElement element value is changed (related to choose element buttons).

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_location_changed -
    -
    -
    -
    - -

    Called when LuaGuiElement element location is changed (related to frames in player.gui.screen).

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_tab_changed -
    -
    -
    -
    - -

    Called when LuaGuiElement selected tab is changed (related to tabbed-panes).

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_selection_changed -
    -
    -
    -
    - -

    Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes).

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_switch_changed -
    -
    -
    -
    - -

    Called when LuaGuiElement switch state is changed (related to switches).

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_text_change -
    -
    -
    -
    - -

    Called when LuaGuiElement text is changed by the player.

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -
    -
    - # - Gui._prototype_element.on_value_changed -
    -
    -
    -
    - -

    Called when LuaGuiElement slider value is changed (related to the slider element).

    -

    - - - -
      - - - - - -
    • - - handler - - : - - (function) - - the event handler which will be called - -
    • - - -
    - - - - - - - - - - - - - -
    -
    -

    Top Flow

    -
    -
    -
    -
    - # - toggle_top_flow -
    -
    -
    -
    - -

    Button which toggles the top flow elements

    +

    Button which toggles the top flow elements, version which shows inside the top flow when top flow is visible

    @@ -1750,14 +1016,14 @@ Gui.element{
    - # - top_flow_button_style + # + show_top_flow
    -

    The style that should be used for buttons on the top flow

    +

    Button which toggles the top flow elements, version which shows inside the left flow when top flow is hidden

    @@ -1777,201 +1043,6 @@ Gui.element{
    - # - get_top_flow(player) -
    -
    -
    -
    - -

    Gets the flow which contains the elements for the top flow

    -

    (player)

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player that you want to get the flow for - -
    • - - -
    - - - - - Returns: - - - - - - - - - Usage: -
    -- Geting your top element flow
    -local top_flow = Gui.get_top_flow(game.player)
    - - -
    -
    -
    -
    - # - update_top_flow(player) -
    -
    -
    -
    - -

    Updates the visible states of all the elements on a players top flow

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player that you want to update the flow for - -
    • - - -
    - - - - - - - - - - - - Usage: -
    -- Update your flow
    -Gui.update_top_flow(game.player)
    - - -
    -
    -
    -
    - # - toggle_top_flow(player[, state]) -
    -
    -
    -
    - -

    Toggles the visible states of all the elements on a players top flow

    -

    - - - Parameters: - -
      - - - - - -
    • - - player - - : - - (LuaPlayer) - - the player that you want to toggle the flow for - -
    • - - - - - -
    • - - state - - : - - (boolean) - - if given then the state will be set to this state - - (optional) -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - the new visible state of the top flow -
    • -
    - - - - - - - - Usage: -
    -- Toggle your flow
    -Gui.toggle_top_flow(game.player)
    -
    -- Open your top flow
    -Gui.toggle_top_flow(game.player,true)
    - - -
    -
    -

    Left Flow

    -
    -
    -
    -
    # hide_left_flow
    @@ -1979,7 +1050,7 @@ Gui.element{
    -

    Button which hides the elements in the left flow

    +

    Button which hides the elements in the left flow, shows inside the left flow when frames are visible

    @@ -1996,21 +1067,24 @@ Gui.element{
    +
    +

    Defines

    +
    - # - get_left_flow(player) + # + alignment
    -

    Gets the flow which contains the elements for the left flow

    -

    (player)

    +

    Draw a flow used to align its child elements, default is right align

    +

    - Parameters: + Properties / Events:
      @@ -2020,59 +1094,15 @@ Gui.element{
    • - player + parent : - (LuaPlayer) - - the player that you want to get the flow for - -
    • - - -
    - - - - - Returns: -
      -
    • (LuaGuiElement) - the left element flow + + the parent element to which the alignment will be added +
    • -
    - - - - - - - - Usage: -
    -- Geting your left element flow
    -local left_flow = Gui.get_left_flow(game.player)
    - - -
    -
    -
    -
    - # - hide_left_flow(player) -
    -
    -
    -
    - -

    Hides all left elements for a player

    -

    - - - Parameters: - -
      @@ -2080,14 +1110,49 @@ Gui.element{
    • - player + name : - (LuaPlayer) + (string) - the player to hide the elements for + the name of the alignment flow which is added + (default: 'alignment') +
    • + + + + + +
    • + + horizontal_align + + : + + (string) + + the horizontal alignment of the elements in the flow + + (default: 'right') +
    • + + + + + +
    • + + vertical_align + + : + + (string) + + the vertical alignment of the elements in the flow + + (default: 'center')
    • @@ -2104,26 +1169,28 @@ Gui.element{ Usage: -
      -- Hide your left elements
      -Gui.hide_left_flow(game.player)
      +
      -- Adding a right align flow
      +local alignment = Gui.alignment(element,'example_right_alignment')
      +
      -- Adding a horizontal center and top align flow
      +local alignment = Gui.alignment(element,'example_center_top_alignment','center','top')
    - # - toggle_left_element(player, element_define[, state]) + # + scroll_table
    -

    Toggles the visible state of all a left element for a player

    +

    Draw a scroll pane that has a table inside of it

    - Parameters: + Properties / Events:
      @@ -2133,13 +1200,13 @@ Gui.element{
    • - player + parent : - (LuaPlayer) + (LuaGuiElement) - the player that you want to toggle the element for + the parent element to which the scroll table will be added
    • @@ -2149,13 +1216,13 @@ Gui.element{
    • - element_define + height : - (table) + (number) - the element that you want to toggle for the player + the maximum height for the scroll pane
    • @@ -2165,13 +1232,533 @@ Gui.element{
    • - state + column_count + + : + + (number) + + the number of columns that the table will have + +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the scroll pane that is added, the table is always called "table" + + (default: 'scroll') +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a scroll table with max height of 200 and column count of 3
    +local scroll_table = Gui.scroll_table(element,200,3)
    + + +
    +
    +
    +
    + # + header +
    +
    +
    +
    + +

    Used to add a frame with the header style, has the option for a right alignment flow for buttons

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the header will be added + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the header + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the header + + (optional) +
    • + + + + + +
    • + + add_alignment : (boolean) - if given then the state will be set to this state + when true an alignment flow will be added to the header + + (default: false) +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the header that is being added, the alignment is always called "alignment" + + (default: 'header') +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a custom header with a label
    +local header = Gui.header(
    +    element,
    +    'Example Caption',
    +    'Example Tooltip'
    +)
    + + +
    +
    +
    +
    + # + footer +
    +
    +
    +
    + +

    Used to add a frame with the footer style, has the option for a right alignment flow for buttons

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the footer will be added + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the footer + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the footer + + (optional) +
    • + + + + + +
    • + + add_alignment + + : + + (boolean) + + when true an alignment flow will be added to the footer + + (default: false) +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the footer that is being added, the alignment is always called "alignment" + + (default: 'footer') +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a custom footer with a label
    +local footer = Gui.footer(
    +    element,
    +    'Example Caption',
    +    'Example Tooltip'
    +)
    + + +
    +
    +
    +
    + # + container +
    +
    +
    +
    + +

    Used for left frames to give them a nice boarder

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the container will be added + +
    • + + + + + +
    • + + name + + : + + (string) + + the name that you want to give to the outer frame, often just event_trigger + +
    • + + + + + +
    • + + width + + : + + (number) + + the minimal width that the frame will have + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a container as a base
    +local container = Gui.container(parent,'my_container',200)
    + + +
    +
    +
    +
    + # + bar +
    +
    +
    +
    + +

    Used to make a solid white bar in a gui

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the bar will be added + +
    • + + + + + +
    • + + width + + : + + (number) + + the width of the bar that will be made, if not given bar will strech to fill the parent + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a bar to a gui
    +local bar = Gui.bar(parent, 100)
    + + +
    +
    +
    +
    + # + centered_label +
    +
    +
    +
    + +

    Used to make a label which is centered and of a certian size

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the label will be added + +
    • + + + + + +
    • + + width + + : + + (number) + + the width of the label, must be given in order to center the caption + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the label + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the label (optional)
    • @@ -2182,13 +1769,6 @@ Gui.element{ - Returns: -
        -
      • - (boolean) - the new visible state of the element -
      • -
      @@ -2197,10 +1777,110 @@ Gui.element{ Usage: -
      -- Toggle your example button
      -Gui.toggle_top_flow(game.player,example_flow_with_button)
      -
      -- Open your example button
      -Gui.toggle_top_flow(game.player,example_flow_with_button,true)
      +
      -- Adding a centered label
      +local label = Gui.centered_label(parent, 100, 'This is centered')
      + + +
    +
    +
    +
    + # + title_label +
    +
    +
    +
    + +

    Used to make a title which has two bars on either side

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the label will be added + +
    • + + + + + +
    • + + width + + : + + (number) + + the width of the first bar, this can be used to position the label + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the label + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the label + + (optional) +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a centered label
    +local label = Gui.centered_label(parent, 100, 'This is centered')
    @@ -2237,7 +1917,7 @@ Gui.element{ (LuaGuiElement) - the element that you want to get the owner of + the element to get the owner of @@ -2297,7 +1977,7 @@ Gui.element{ (LuaGuiElement) - the element that you want to toggle the state of + the element to toggle/set the enabled state of @@ -2313,7 +1993,7 @@ Gui.element{ (boolean) - the state that you want to set + with given will set the state, else state will be toggled (optional) @@ -2374,7 +2054,7 @@ Gui.element{ (LuaGuiElement) - the element that you want to toggle the state of + the element to toggle/set the visible state of @@ -2390,7 +2070,7 @@ Gui.element{ (boolean) - the state that you want to set + with given will set the state, else state will be toggled (optional) @@ -2431,7 +2111,7 @@ Gui.element{
    -

    Destory a gui element without causing any errors, likly if the element may have already been removed

    +

    Destory a gui element without causing any errors, often because the element was already removed

    @@ -2476,7 +2156,7 @@ Gui.element{ Usage: -
    -- Likely use case for element not existing
    +    
    -- Remove a child element if it exists
     Gui.destroy_if_valid(element[child_name])
    @@ -2484,14 +2164,14 @@ Gui.element{
    - # - alignment(parent[, horizontal_align='right'][, vertical_align='center'][, name='alignment']) + # + sprite_style(size[, padding=-2][, style])
    -

    Draw a flow that has custom element alignments, default is right align

    +

    Returns a table to be used as the style for a sprite buttons, produces a sqaure button

    @@ -2505,13 +2185,13 @@ Gui.element{
  • - parent + size : - (LuaGuiElement) + (number) - the parent element that the alignment flow will be added to + the size that you want the button to be
  • @@ -2521,15 +2201,15 @@ Gui.element{
  • - horizontal_align + padding : - (string) + (number) - the horizontal alignment of the elements in the flow + the padding that you want on the sprite - (default: 'right') + (default: -2)
  • @@ -2538,32 +2218,110 @@ Gui.element{
  • - vertical_align + style : - (string) + (table) - the vertical alignment of the elements in the flow + any extra style settings that you want to have - (default: 'center') + (optional)
  • + + + + + + Returns: +
      +
    • + (table) + the style table to be used with element_define:style() +
    • +
    + + + + + + + + Usage: +
    -- Adding a sprite button with size 20
    +local button =
    +Gui.element{
    +    type = 'sprite-button',
    +    sprite = 'entity/inserter'
    +}
    +:style(Gui.sprite_style(20))
    + + +
    +
    +

    Left Flow

    +
    +
    +
    +
    + # + left_elements +
    +
    +
    +
    + +

    Contains the uids of the elements that will shown on the left flow and their join functions

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + get_left_flow(player) +
    +
    +
    +
    + +

    Gets the flow refered to as the left flow, each player has one left flow

    +

    (player)

    + + + Parameters: + +
      + +
    • - name + player : - (string) + (LuaPlayer) - the name of the alignment flow + the player that you want to get the left flow for - (default: 'alignment')
    • @@ -2576,7 +2334,7 @@ Gui.element{
      • (LuaGuiElement) - the alignment flow that was created + the left element flow
      @@ -2587,24 +2345,22 @@ Gui.element{ Usage: -
      -- Adding a right align flow
      -local alignment = Gui.alignment(element,'example_right_alignment')
      -
      -- Adding a horizontal center and top align flow
      -local alignment = Gui.alignment(element,'example_center_top_alignment','center','top')
      +
      -- Geting your left flow
      +local left_flow = Gui.get_left_flow(game.player)
    - # - scroll_table(parent, height, column_count[, name='scroll']) + # + Gui._prototype_element:add_to_left_flow([open_on_join])
    -

    Draw a scroll pane that has a table inside of it

    +

    Sets an element define to be drawn to the left flow when a player joins, includes optional check

    @@ -2618,63 +2374,15 @@ Gui.element{
  • - parent + open_on_join : - (LuaGuiElement) + (boolean or function) - the parent element that the scroll table will be added to + called during first darw to decide if the element should be visible -
  • - - - - - -
  • - - height - - : - - (number) - - the maximum height for the scroll pane - -
  • - - - - - -
  • - - column_count - - : - - (number) - - the number of columns that the table will have - -
  • - - - - - -
  • - - name - - : - - (string) - - the name of the scroll pane that is added, the table is always called 'table' - - (default: 'scroll') + (optional)
  • @@ -2686,8 +2394,8 @@ Gui.element{ Returns:
    • - (LuaGuiElement) - the table that was created + (table) + the new element define that is used to register events to this element
    @@ -2698,22 +2406,22 @@ Gui.element{ Usage: -
    -- Adding a scroll table with max height of 200 and column count of 3
    -local scroll_table = Gui.scroll_table(element,'example_scroll_table',200,3)
    +
    -- Adding the example button
    +example_flow_with_button:add_to_left_flow(true)
    - # - header(parent, caption[, tooltip][, add_alignment=false][, name='header']) + # + left_toolbar_button(sprite, tooltip, element_define[, authenticator])
    -

    Used to add a header to a frame, this has the option for a custom right alignment flow for buttons

    +

    Creates a button on the top flow which will toggle the given element define, the define must exist in the left flow

    @@ -2727,29 +2435,13 @@ Gui.element{
  • - parent + sprite : - (LuaGuiElement) + (string) - the parent element that the header will be added to - -
  • - - - - - -
  • - - caption - - : - - (string or LocalizedString) - - the caption that will be shown on the header + the sprite that you want to use on the button
  • @@ -2765,26 +2457,263 @@ Gui.element{ (string or LocalizedString) - the tooltip that will be shown on the header + the tooltip that you want the button to have + + + + + + + +
  • + + element_define + + : + + (table) + + the element define that you want to have toggled by this button, define must exist on the left flow + +
  • + + + + + +
  • + + authenticator + + : + + (function) + + used to decide if the button should be visible to a player (optional)
  • + + + + + + + + + + + + + Usage: +
    -- Add a button to toggle a left element
    +local toolbar_button =
    +Gui.left_toolbar_button('entity/inserter', 'Nothing to see here', example_flow_with_button, function(player)
    +    return player.admin
    +end)
    + + +
    +
    +
    +
    + # + draw_left_flow(player) +
    +
    +
    +
    + +

    Draw all the left elements onto the left flow, internal use only with on join

    +

    + + + Parameters: + +
      + +
    • - add_alignment + player : + (LuaPlayer) + + the player that you want to draw the elements for + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Draw all the left elements
    +Gui.draw_left_flow(player)
    + + +
    +
    +
    +
    + # + update_left_flow(player) +
    +
    +
    +
    + +

    Update the visible state of the hide button, can be used to check if any frames are visible

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player to update the left flow for + +
    • + + +
    + + + + + Returns: +
      +
    • (boolean) + true if any left element is visible +
    • +
    + - when true an alignment flow will be added for buttons - (default: false) + + + + + Usage: +
    -- Check if any left elements are visible
    +local visible = Gui.update_left_flow(player)
    + + +
    +
    +
    +
    + # + hide_left_flow(player) +
    +
    +
    +
    + +

    Hides all left elements for a player

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player to hide the elements for + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Hide your left elements
    +Gui.hide_left_flow(game.player)
    + + +
    +
    +
    +
    + # + get_left_element(player, element_define) +
    +
    +
    +
    + +

    Get the element define that is in the left flow, use in events without an element refrence

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to get the element for +
    • @@ -2793,15 +2722,14 @@ Gui.element{
    • - name + element_define : - (string) + (table) - the name of the header that is being added, the alignment is always called 'alignment' + the element that you want to get - (default: 'header')
    • @@ -2814,7 +2742,7 @@ Gui.element{
      • (LuaGuiElement) - either the header or the header alignment if add_alignment is true + the gui element linked to this define for this player
      @@ -2825,14 +2753,1640 @@ Gui.element{ Usage: -
      -- Adding a custom header
      -local header_alignment = Gui.header(
      -    element,
      -    'example_header',
      -    'Example Caption',
      -    'Example Tooltip',
      -    true
      -)
      +
      -- Get your left element
      +local frame = Gui.get_left_element(game.player, example_flow_with_button)
      + + +
    +
    +
    +
    + # + toggle_left_element(player, element_define[, state]) +
    +
    +
    +
    + +

    Toggles the visible state of a left element for a given player, can be used to set the visible state

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to toggle the element for + +
    • + + + + + +
    • + + element_define + + : + + (table) + + the element that you want to toggle + +
    • + + + + + +
    • + + state + + : + + (boolean) + + with given will set the state, else state will be toggled + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new visible state of the element +
    • +
    + + + + + + + + Usage: +
    -- Toggle your example button
    +Gui.toggle_top_flow(game.player, example_flow_with_button)
    +
    -- Show your example button
    +Gui.toggle_top_flow(game.player, example_flow_with_button, true)
    + + +
    +
    +

    Element Define

    +
    +
    +
    +
    + # + element(element_define) +
    +
    +
    +
    + +

    Used to define new elements for your gui, can be used like LuaGuiElement.add or a custom function

    +

    + + + Parameters: + +
      + + + + + +
    • + + element_define + + : + + (table or function) + + the define information for the gui element, same data as LuaGuiElement.add, or a custom function may be used + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the new element define, this can be considered a factory for the element which can be called to draw the element to any other element +
    • +
    + + + + + + + + Usage: +
    -- Using element defines like LuaGuiElement.add
    +-- This returns a factory function to draw a button with the caption "Example Button"
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button'
    +}
    +
    -- Using element defines with a custom factory function
    +-- This method can be used if you still want to be able register event handlers but it is too complex to be compatible with LuaGuiElement.add
    +local example_flow_with_button =
    +Gui.element(function(event_trigger,parent,...)
    +    -- ... shows that all other arguments from the factory call are passed to this function
    +    -- parent is the element which was passed to the factory function where you should add your new element
    +    -- here we are adding a flow which we will then later add a button to
    +    local flow =
    +    parent.add{
    +        name = 'example_flow',
    +        type = 'flow'
    +    }
    +
    +    -- event_trigger should be the name of any elements you want to trigger your event handlers, such as on_click or on_state_changed
    +    -- now we add the button to the flow that we created earlier
    +    local element =
    +    flow.add{
    +        name = event_trigger,
    +        type = 'button',
    +        caption = 'Example Button'
    +    }
    +
    +    -- you must return your new element, this is so styles can be applied and returned to the caller
    +    -- you may return any of your elements that you add, consider the context in which it will be used for what should be returned
    +    return element
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:style(style_define) +
    +
    +
    +
    + +

    Used to extent your element define with a style factory, this style will be applied to your element when created, can also be a custom function

    +

    + + + Parameters: + +
      + + + + + +
    • + + style_define + + : + + (table or function) + + style table where each key and value pair is treated like LuaGuiElement.style[key] = value, a custom function can be used + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the element define is returned to allow for event handlers to be registered +
    • +
    + + + + + + + + Usage: +
    -- Using the table method of setting the style
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button',
    +    style = 'forward_button' -- factorio styles can be applied here
    +}
    +:style{
    +    height = 25, -- same as element.style.height = 25
    +    width = 100 -- same as element.style.width = 25
    +}
    +
    -- Using the function method to set the style
    +-- Use this method if your style is dynamic and depends on other factors
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button',
    +    style = 'forward_button' -- factorio styles can be applied here
    +}
    +:style(function(style,element,...)
    +    -- style is the current style object for the elemenent
    +    -- element is the element that is being changed
    +    -- ... shows that all other arguments from the factory call are passed to this function
    +    local player = game.players[element.player_index]
    +    style.height = 25
    +    style.width = 100
    +    style.font_color = player.color
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:on_custom_event(event_name, handler) +
    +
    +
    +
    + +

    Set the handler which will be called for a custom event, only one handler can be used per event per element

    +

    + + + Parameters: + +
      + + + + + +
    • + + event_name + + : + + (string) + + the name of the event you want to handler to be called on, often from Gui.events + +
    • + + + + + +
    • + + handler + + : + + (function) + + the handler that you want to be called when the event is raised + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the element define so more handleres can be registered +
    • +
    + + + + + + + + Usage: +
    -- Register a handler to "my_custom_event" for this element
    +element_deinfe:on_custom_event('my_custom_event', function(event)
    +    event.player.print(player.name)
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:raise_custom_event(event) +
    +
    +
    +
    + +

    Raise the handler which is attached to an event; external use should be limited to custom events

    +

    + + + Parameters: + +
      + + + + + +
    • + + event + + : + + (table) + + the event table passed to the handler, must contain fields: name, element + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the element define so more events can be raised +
    • +
    + + + + + + + + Usage: +
     Raising a custom event
    +element_define:raise_custom_event{
    +    name = 'my_custom_event',
    +    element = element
    +}
    + + +
    +
    +

    Element Events

    +
    +
    +
    +
    + # + Gui._prototype_element.on_open +
    +
    +
    +
    + +

    Called when the player opens a GUI.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_open(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_close +
    +
    +
    +
    + +

    Called when the player closes the GUI they have open.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_close(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_click +
    +
    +
    +
    + +

    Called when LuaGuiElement is clicked.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_click(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_confirmed +
    +
    +
    +
    + +

    Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_confirmed(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_checked_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_checked_changed(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_elem_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement element value is changed (related to choose element buttons).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_elem_changed(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_location_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement element location is changed (related to frames in player.gui.screen).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_location_changed(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_tab_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement selected tab is changed (related to tabbed-panes).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_tab_changed(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_selection_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_selection_changed(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_switch_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement switch state is changed (related to switches).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_switch_changed(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_text_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement text is changed by the player.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_text_changed(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element.on_value_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement slider value is changed (related to the slider element).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + Usage: +
     element_define:on_value_changed(function(event)
    +  event.player.print(table.inspect(event))
    +end)
    + + +
    +
    +

    Top Flow

    +
    +
    +
    +
    + # + top_elements +
    +
    +
    +
    + +

    Contains the uids of the elements that will shown on the top flow and their auth functions

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + top_flow_button_style +
    +
    +
    +
    + +

    The style that should be used for buttons on the top flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + top_flow_button_visible_style +
    +
    +
    +
    + +

    The style that should be used for buttons on the top flow when their flow is visible

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + get_top_flow(player) +
    +
    +
    +
    + +

    Gets the flow refered to as the top flow, each player has one top flow

    +

    (player)

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to get the flow for + +
    • + + +
    + + + + + Returns: + + + + + + + + + Usage: +
    -- Geting your top flow
    +local top_flow = Gui.get_top_flow(game.player)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:add_to_top_flow([authenticator]) +
    +
    +
    +
    + +

    Sets an element define to be drawn to the top flow when a player joins, includes optional authenticator

    +

    + + + Parameters: + +
      + + + + + +
    • + + authenticator + + : + + (function) + + called during toggle or update to decide weather the element should be visible + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the new element define to allow event handlers to be registered +
    • +
    + + + + + + + + Usage: +
    -- Adding an element to the top flow on join
    +example_button:add_to_top_flow(function(player)
    +    -- example button will only be shown if the player is an admin
    +    -- note button will not update its state when player.admin is changed Gui.update_top_flow must be called for this
    +    return player.admin
    +end)
    + + +
    +
    +
    +
    + # + update_top_flow(player) +
    +
    +
    +
    + +

    Updates the visible state of all the elements on the players top flow, uses authenticator

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to update the top flow for + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Update your top flow
    +Gui.update_top_flow(game.player)
    + + +
    +
    +
    +
    + # + toggle_top_flow(player[, state]) +
    +
    +
    +
    + +

    Toggles the visible state of all the elements on a players top flow, effects all elements

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to toggle the top flow for + +
    • + + + + + +
    • + + state + + : + + (boolean) + + if given then the state will be set to this + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new visible state of the top flow +
    • +
    + + + + + + + + Usage: +
    -- Toggle your flow
    +Gui.toggle_top_flow(game.player)
    +
    -- Open your top flow
    +Gui.toggle_top_flow(game.player,true)
    + + +
    +
    +
    +
    + # + get_top_element(player, element_define) +
    +
    +
    +
    + +

    Get the element define that is in the top flow, use in events without an element refrence

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to get the element for + +
    • + + + + + +
    • + + element_define + + : + + (table) + + the element that you want to get + +
    • + + +
    + + + + + Returns: +
      +
    • + (LuaGuiElement) + the gui element linked to this define for this player +
    • +
    + + + + + + + + Usage: +
    -- Get your top element
    +local button = Gui.get_top_element(game.player, example_button)
    + + +
    +
    +
    +
    + # + toolbar_button(sprite, tooltip[, authenticator]) +
    +
    +
    +
    + +

    Creates a button on the top flow with consistent styling

    +

    + + + Parameters: + +
      + + + + + +
    • + + sprite + + : + + (string) + + the sprite that you want to use on the button + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that you want the button to have + +
    • + + + + + +
    • + + authenticator + + : + + (function) + + used to decide if the button should be visible to a player + + (optional) +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Add a button to the toolbar
    +local toolbar_button =
    +Gui.left_toolbar_button('entity/inserter', 'Nothing to see here', function(player)
    +    return player.admin
    +end)
    + + +
    +
    +
    +
    + # + toolbar_button_style(button, state) +
    +
    +
    +
    + +

    Styles a top flow button depending on the state given

    +

    + + + Parameters: + +
      + + + + + +
    • + + button + + : + + (LuaGuiElement) + + the button element to style + +
    • + + + + + +
    • + + state + + : + + (boolean) + + The state the button is in + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Sets the button to the visible style
    +Gui.toolbar_button_style(button, true)
    +
    -- Sets the button to the hidden style
    +Gui.toolbar_button_style(button, false)
    @@ -2851,7 +4405,7 @@ Gui.element{ generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index dc36167e..41fde465 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -53,13 +53,13 @@ @@ -88,10 +88,12 @@ + + @@ -100,8 +102,10 @@

    Guis

    @@ -139,7 +143,6 @@

    Configs

    @@ -172,18 +176,13 @@

    Modules

    @@ -230,7 +229,7 @@

    Permissions-Groups core

    Core Module - Permission Groups - - Permission group making for factorio so you never have to make one by hand again

    +- Permission group making for factorio so you never have to make one by hand again

    @@ -239,26 +238,22 @@

    Usage

    -
    
    ----- Example Group (Allow All)
    -
    -    -- here we will create an admin group however we do not want them to use the map editor or mess with the permission groups
    -    Permission_Groups.new_group('Admin') -- this defines a new group called "Admin"
    -    :allow_all() -- this makes the default to allow any input action unless set other wise
    -    :disallow{ -- here we disallow the input action we don't want them to use
    -        'add_permission_group',
    -        'delete_permission_group',
    -        'import_permissions_string',
    -        'map_editor_action',
    -        'toggle_map_editor'
    -    }
    -
    
    ----- Example Group (Disallow All)
    -
    -    -- here we will create a group that cant do anything but talk in chat
    -    Permission_Groups.new_group('Restricted') -- this defines a new group called "Restricted"
    -    :disallow_all() -- this makes the default to disallow any input action unless set other wise
    -    :allow('write_to_console') -- here we allow them to chat, {} can be used here if we had more than one action
    +    
    --- Example Group (Allow All)
    +-- here we will create an admin group however we do not want them to use the map editor or mess with the permission groups
    +Permission_Groups.new_group('Admin') -- this defines a new group called "Admin"
    +:allow_all() -- this makes the default to allow any input action unless set other wise
    +:disallow{ -- here we disallow the input action we don't want them to use
    +    'add_permission_group',
    +    'delete_permission_group',
    +    'import_permissions_string',
    +    'map_editor_action',
    +    'toggle_map_editor'
    +}
    +
    --- Example Group (Disallow All)
    +-- here we will create a group that cant do anything but talk in chat
    +Permission_Groups.new_group('Restricted') -- this defines a new group called "Restricted"
    +:disallow_all() -- this makes the default to disallow any input action unless set other wise
    +:allow('write_to_console') -- here we allow them to chat, {} can be used here if we had more than one action
     
    @@ -278,7 +273,7 @@ utils.event - expcore.sudo + expcore.async @@ -313,10 +308,6 @@ Reloads/creates all permission groups and sets them to they configured state - lockdown_permissions(exempt) - Removes all permissions from every permission group except for "Default" and any passed as exempt - - set_player_group(player, group) Sets a player's group to the one given, a player can only have one group at a time @@ -361,14 +352,14 @@ - Permissions_Groups._prototype:get_raw() - Returns the LuaPermissionGroup that was created with this group object, used internally - - Permissions_Groups._prototype:create() Creates or updates the permission group with the configured actions, used internally + Permissions_Groups._prototype:get_raw() + Returns the LuaPermissionGroup that was created with this group object, used internally + + Permissions_Groups._prototype:add_player(player) Adds a player to this group @@ -446,8 +437,8 @@
    - # - expcore.sudo + # + expcore.async
    @@ -525,6 +516,9 @@ + Usage: +
    -- Defining a new permission group
    +Groups.new_group('Admin')
    @@ -582,6 +576,9 @@ + Usage: +
    -- Getting a permision group
    +local admin_group = Groups.get_group_by_name('Admin')
    @@ -639,6 +636,9 @@ + Usage: +
    -- Get your permission group
    +local group = Groups.get_group_from_player(game.player)
    @@ -669,63 +669,9 @@ - - - -
    -
    -
    - # - lockdown_permissions(exempt) -
    -
    -
    -
    - -

    Removes all permissions from every permission group except for "Default" and any passed as exempt

    -

    - - - Parameters: - -
      - - - - - -
    • - - exempt - - : - - (string or Array) - - groups that you want to be except, "Default" is always exempt - -
    • - - -
    - - - - - Returns: -
      -
    • - (number) - the number of groups that had they permissions removed -
    • -
    - - - - - - - + Usage: +
    -- Reload the permission groups, used internally
    +Groups.reload_permissions()
    @@ -799,6 +745,9 @@ + Usage: +
    -- Set your permission group
    +Groups.set_player_group(game.player, 'Admin')
    @@ -875,6 +824,9 @@ + Usage: +
    -- Set an action to be disalowed
    +group:set_action('toggle_map_editor', false)
    @@ -932,6 +884,11 @@ + Usage: +
    -- Allow some actions
    +group:allow{
    +    'write_to_console'
    +}
    @@ -989,6 +946,15 @@ + Usage: +
    -- Disalow some actions
    +group:disallow{
    +    'add_permission_group',
    +    'delete_permission_group',
    +    'import_permissions_string',
    +    'map_editor_action',
    +    'toggle_map_editor'
    +}
    @@ -1023,6 +989,9 @@ + Usage: +
    -- Allow all actions unless given by disallow
    +group:allow_all()
    @@ -1057,6 +1026,9 @@ + Usage: +
    -- Disallow all actions unless given by allow
    +group:disallow_all()
    @@ -1114,6 +1086,9 @@ + Usage: +
    -- Test if a group is allowed an action
    +local allowed = group:is_allowed('write_to_console')
    @@ -1123,40 +1098,6 @@
    - # - Permissions_Groups._prototype:get_raw() -
    -
    -
    -
    - -

    Returns the LuaPermissionGroup that was created with this group object, used internally

    -

    - - - - - - Returns: - - - - - - - - - - -
    -
    -
    -
    # Permissions_Groups._prototype:create()
    @@ -1185,6 +1126,46 @@ + Usage: +
    -- Create the permission group so players can be added, used internally
    +group:create()
    + + + +
    +
    +
    + # + Permissions_Groups._prototype:get_raw() +
    +
    +
    +
    + +

    Returns the LuaPermissionGroup that was created with this group object, used internally

    +

    + + + + + + Returns: + + + + + + + + + Usage: +
    -- Get the factorio api permision group, used internally
    +local permission_group = group:get_raw()
    @@ -1242,6 +1223,9 @@ + Usage: +
    -- Add a player to this permission group
    +group:add_player(game.player)
    @@ -1299,6 +1283,9 @@ + Usage: +
    -- Remove a player from this permission group
    +group:remove_player(game.player)
    @@ -1357,6 +1344,11 @@ + Usage: +
    -- Get all players in this group
    +local online_players = group:get_players()
    +
    -- Get all online players in this group
    +local online_players = group:get_players(true)
    @@ -1414,6 +1406,9 @@ + Usage: +
    -- Print a message to all players in thie group
    +group:print('Hello, World!')
    @@ -1432,7 +1427,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index 25ceecf4..5a2def19 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -57,13 +57,13 @@ @@ -92,10 +92,12 @@ + + @@ -104,8 +106,10 @@

    Guis

    @@ -143,7 +147,6 @@

    Configs

    @@ -176,18 +180,13 @@

    Modules

    @@ -238,7 +237,7 @@

    Roles core

    Core Module - Roles - - Factorio role system to manage custom permissions.

    +- Factorio role system to manage custom permissions.

    @@ -247,111 +246,107 @@

    Usage

    -
    
    ----- Using Role System (Frontend):
    -    When a map first starts you will want to define on mass all the players you expect to join and the roles to give them:
    -    Roles.override_player_roles{
    -        Cooldude2606 = {'Owner','Admin','Member'},
    -        NotCooldude2606 = {'Member'}
    -    }
    +    
    --- Using Role System (assignment):
    +--When a map first starts you will want to define on mass all the players you expect to join and the roles to give them:
    +Roles.override_player_roles{
    +    Cooldude2606 = {'Owner','Admin','Member'},
    +    NotCooldude2606 = {'Member'}
    +}
     
    -    Once the game is running you still want to be able to give role and remove them which is when you would use:
    -    Roles.assign_player(player,'Admin',by_player_name) -- this will give the "Admin" role to the player
    -    Roles.unassign_player(player,{'Admin','Moderator'},by_player_name) -- this will remove "Admin" and "Moderator" role in one go
    +--Once the game is running you still want to be able to give role and remove them which is when you would use:
    +Roles.assign_player(player,'Admin',by_player_name) -- this will give the "Admin" role to the player
    +Roles.unassign_player(player,{'Admin','Moderator'},by_player_name) -- this will remove "Admin" and "Moderator" role in one go
     
    -
    
    ----- Using Role System (Backend):
    -    To comparer two players you can comparer the index of they highest roles, can be used when you want to allow a "write" down type system:
    -    Roles.get_player_highest_role(playerOne).index < Roles.get_player_highest_role(playerTwo).index -- remember that less means a higher role
    +    
    --- Using Role System (role testing):
    +--To comparer two players you can comparer the index of they highest roles, can be used when you want to allow a "write" down type system:
    +Roles.get_player_highest_role(playerOne).index < Roles.get_player_highest_role(playerTwo).index -- remember that less means a higher role
     
    -    Listing all of a players roles can also be useful which is when you would want to use:
    -    Roles.get_player_roles(player) -- the return is an array that can be looped over however this is not in particular order
    +--Listing all of a players roles can also be useful which is when you would want to use:
    +Roles.get_player_roles(player) -- the return is an array that can be looped over however this is not in particular order
     
    -    Finally you may want to test if a player has a certain role, flag or action allowed which is when you would use:
    -    Roles.player_has_role(player,'Admin') -- you can provide a role name if you only want a name based system
    -    Roles.player_has_flag(player,'is_donator') -- your roles can be grouped together with flags such as is_donator
    -    Roles.player_allowed(player,'game modifiers') -- or you can have an action based system where each action is something the player can do
    +--Finally you may want to test if a player has a certain role, flag or action allowed which is when you would use:
    +Roles.player_has_role(player,'Admin') -- you can provide a role name if you only want a name based system
    +Roles.player_has_flag(player,'is_donator') -- your roles can be grouped together with flags such as is_donator
    +Roles.player_allowed(player,'game modifiers') -- or you can have an action based system where each action is something the player can do
     
    -
    
    ----- Example Flag Define:
    -    Flags can be used to group multiple roles and actions under one catch all, for example if you want a piece of code to only
    -    be active for your donators then you would add a "is_donator" flag to all your donator roles and then in the code test if
    -    a player has that tag present:
    +    
    --- Example Flag Define:
    +--Flags can be used to group multiple roles and actions under one catch all, for example if you want a piece of code to only
    +--be active for your donators then you would add a "is_donator" flag to all your donator roles and then in the code test if
    +--a player has that tag present:
    +
    +-- give you donators a speed boost when they join; these functions aren't required but can be useful
    +Roles.define_flag_trigger('is_donator',function(player,state)
    +    if state then
    +        player.character_running_speed_modifier = 1.5
    +    else
    +        player.character_running_speed_modifier = 1
    +    end
    +end)
     
    -    -- give you donators a speed boost when they join; these functions aren't required but can be useful
    -    Roles.define_flag_trigger('is_donator',function(player,state)
    -        if state then
    -            player.character_running_speed_modifier = 1.5
    -        else
    -            player.character_running_speed_modifier = 1
    -        end
    -    end)
    +-- then on all your donator roles you would add
    +Roles.new_role('Donator')
    +:set_flag('is_donator')
     
    -    -- then on all your donator roles you would add
    -    Roles.new_role('Donator')
    -    :set_flag('is_donator')
    +-- and in your code you would test for
    +if Roles.player_has_flag(player,'is_donator') then
    +    -- some donator only code
    +end
    +
    --- Example Role Define:
    +--You can't use a role system without any roles so first you must define your roles; each role has a minimum of a name with
    +--the option for a shorthand:
    +Roles.new_role('Administrator','Admin')
     
    -    -- and in your code you would test for
    -    if Roles.player_has_flag(player,'is_donator') then
    -        -- some donator only code
    -    end
    -
    
    ----- Example Role Define:
    -    You can't use a role system without any roles so first you must define your roles; each role has a minimum of a name with
    -    the option for a shorthand:
    -    Roles.new_role('Administrator','Admin')
    +--Next you will want to add any extras you want to have, such as a tag, colour, permission group or any custom flags:
    +Roles.new_role('Administrator','Admin')
    +:set_custom_tag('[Admin]')
    +:set_custom_color('red') -- this can be {r=0,g=0,b=0} or a predefined value
    +:set_permission_group('Staff') -- a second argument can be added if you have not used the custom permission group config
    +:set_flag('is_admin')
     
    -    Next you will want to add any extras you want to have, such as a tag, colour, permission group or any custom flags:
    -    Roles.new_role('Administrator','Admin')
    -    :set_custom_tag('[Admin]')
    -    :set_custom_color('red') -- this can be {r=0,g=0,b=0} or a predefined value
    -    :set_permission_group('Staff') -- a second argument can be added if you have not used the custom permission group config
    -    :set_flag('is_admin')
    +--You will then want to decide if you want to allow all actions, this should of course be used sparely:
    +Roles.new_role('Administrator','Admin')
    +...extras...
    +:set_allow_all()
     
    -    You will then want to decide if you want to allow all actions, this should of course be used sparely:
    -    Roles.new_role('Administrator','Admin')
    -    ...extras...
    -    :set_allow_all()
    +--If you don't do this want this as i would advise you do then you will want to define what the role can do; this comes with
    +--an optional inheritance system if you like those sort of things in which case disallow may also be of some use to you:
    +Roles.new_role('Administrator','Admin')
    +...extras...
    +:set_parent('Moderator') -- the admin can do anything that a moderator can do
    +:allow{ -- these actions can be anything just try to keep them without conflicts
    +    'command/kill',
    +    'gui/game settings'
    +}
     
    -    If you don't do this want this as i would advise you do then you will want to define what the role can do; this comes with
    -    an optional inheritance system if you like those sort of things in which case disallow may also be of some use to you:
    -    Roles.new_role('Administrator','Admin')
    -    ...extras...
    -    :set_parent('Moderator') -- the admin can do anything that a moderator can do
    -    :allow{ -- these actions can be anything just try to keep them without conflicts
    -        'command/kill',
    -        'gui/game settings'
    -    }
    +--Here is what the finished admin role would look like:
    +Roles.new_role('Administrator','Admin')
    +:set_custom_tag('[Admin]')
    +:set_custom_color('red')
    +:set_permission_group('Staff')
    +:set_flag('is_admin')
    +:set_parent('Moderator')
    +:allow{
    +    'command/kill',
    +    'gui/game settings'
    +}
    +
    --- Example System Define:
    +--Once all roles are defined these steps must be done to ensure the system is ready to use, this includes setting a default
    +--role, assigning a root (all permission) role that the server/system will use and the linear order that the roles fall into:
    +
    +Roles.set_default('Guest')
    +Roles.set_root('System')
     
    -    Here is what the finished admin role would look like:
    -    Roles.new_role('Administrator','Admin')
    -    :set_custom_tag('[Admin]')
    -    :set_custom_color('red')
    -    :set_permission_group('Staff')
    -    :set_flag('is_admin')
    -    :set_parent('Moderator')
    -    :allow{
    -        'command/kill',
    -        'gui/game settings'
    -    }
    -
    
    ----- Example System Define:
    -    Once all roles are defined these steps must be done to ensure the system is ready to use, this includes setting a default
    -    role, assigning a root (all permission) role that the server/system will use and the linear order that the roles fall into:
    +Roles.define_role_order{
    +    'System',
    +    'Administrator',
    +    'Moderator',
    +    'Donator',
    +    'Guest'
    +}
     
    -    Roles.set_default('Guest')
    -    Roles.set_root('System')
    -
    -    Roles.define_role_order{
    -        'System',
    -        'Administrator',
    -        'Moderator',
    -        'Donator',
    -        'Guest'
    -    }
    -
    -    Just remember that in this example all these roles have not been defined; so make sure all your roles that are used are defined
    -    before hand; a config file on load is useful for this to ensure that its loaded before the first player even joins.
    +--Just remember that in this example all these roles have not been defined; so make sure all your roles that are used are defined +--before hand; a config file on load is useful for this to ensure that its loaded before the first player even joins. +
    @@ -376,10 +371,10 @@ expcore.permission_groups - expcore.sudo + expcore.async - resources.color_presets + utils.color_presets expcore.common @@ -419,7 +414,7 @@ get_role_from_any(any) Gets a role from a name,index or role object (where it is just returned) - nb: this function is used for the input for most outward facing functions +nb: this function is used for the input for most outward facing functions get_player_roles(player) @@ -438,15 +433,15 @@ - assign_player(player, roles[, by_player_name=][, silent=false]) + assign_player(player, roles[, by_player_name=][, skip_checks=false][, silent=false]) Gives a player the given role(s) with an option to pass a by player name used in the log - unassign_player(player, roles[, by_player_name=][, silent=false]) + unassign_player(player, roles[, by_player_name=][, skip_checks=false][, silent=false]) Removes a player from the given role(s) with an option to pass a by player name used in the log - override_player_roles(roles) + override_player_roles([player_name], roles) Overrides all player roles with the given table of roles, useful to mass set roles on game start @@ -480,7 +475,7 @@ define_role_order(order) Used to set the role order, higher in the list is better, must be called at least once in config - nb: function also re links parents due to expected position in the config file +-- nb: function also re links parents due to expected position in the config file define_flag_trigger(name, callback) @@ -565,16 +560,16 @@ Roles._prototype:set_parent(role) Sets the parent for a role, any action not in allow or disallow will be looked for in its parents - nb: this is a recursive action, and changing the allows and disallows will effect all children roles +nb: this is a recursive action, and changing the allows and disallows will effect all children roles - Roles._prototype:set_auto_promote_condition(callback) - Sets an auto promote condition that is checked every 5 seconds, if true is returned then the player will receive the role - nb: this is one way, failing false after already gaining the role will not revoke the role + Roles._prototype:set_auto_assign_condition(callback) + Sets an auto assign condition that is checked every 60 seconds, if true is returned then the player will receive the role +nb: this is one way, failing false after already gaining the role will not revoke the role Roles._prototype:set_block_auto_promote([state=true]) - Sets the role to not allow players to have auto promote effect them, useful to keep people locked to a punishment + Sets the role to not allow players to have auto assign effect them, useful to keep people locked to a role @@ -712,8 +707,8 @@
    - # - expcore.sudo + # + expcore.async
    @@ -737,8 +732,8 @@
    - # - resources.color_presets + # + utils.color_presets
    @@ -818,6 +813,9 @@ + Usage: +
    -- Print the debug string
    +game.player.print(Roles.debug())
    @@ -884,6 +882,9 @@ + Usage: +
    -- Print a message to the given roles
    +Roles.print_to_roles({'Administrator','Moderator'}, 'Hello, World!')
    @@ -950,6 +951,9 @@ + Usage: +
    -- Print a message to the roles above this role, includes the given role
    +Roles.print_to_roles_higher('Moderator', 'Hello, World!')
    @@ -1016,6 +1020,9 @@ + Usage: +
    -- Print a message to the roles below this role, includes the given role
    +Roles.print_to_roles_higher('Moderator', 'Hello, World!')
    @@ -1073,6 +1080,9 @@ + Usage: +
    -- Get a role by its name
    +local role = Roles.get_role_by_name('Moderator')
    @@ -1130,6 +1140,9 @@ + Usage: +
    -- Get a role by its index in the order list
    +local role = Roles.get_role_by_name(2)
    @@ -1144,7 +1157,7 @@

    Gets a role from a name,index or role object (where it is just returned) - nb: this function is used for the input for most outward facing functions

    +nb: this function is used for the input for most outward facing functions

    @@ -1188,6 +1201,9 @@ + Usage: +
    -- Get a role by its name or order
    +local role = Roles.get_role_from_any('Moderator')
    @@ -1245,6 +1261,9 @@ + Usage: +
    -- Get the roles that a player has
    +local roles = Roles.get_player_roles(game.player)
    @@ -1302,6 +1321,9 @@ + Usage: +
    -- Get the highest role that a player has
    +local role = Roles.get_player_highest_role(game.player)
    @@ -1312,7 +1334,7 @@
    # - assign_player(player, roles[, by_player_name=][, silent=false]) + assign_player(player, roles[, by_player_name=][, skip_checks=false][, silent=false])
    @@ -1379,6 +1401,23 @@ +
  • + + skip_checks + + : + + (boolean) + + when true there will be no checks are done for if the player is valid + + (default: false) +
  • + + + + +
  • silent @@ -1405,6 +1444,11 @@ + Usage: +
    -- Assign a player to the Moderator role
    +Roles.assign_player(game.player,  'Moderator')
    +
    -- Assign a player to the Moderator role, even if the player has never been on the map
    +Roles.assign_player('Cooldude2606',  'Moderator', nil, true)
  • @@ -1412,7 +1456,7 @@
    # - unassign_player(player, roles[, by_player_name=][, silent=false]) + unassign_player(player, roles[, by_player_name=][, skip_checks=false][, silent=false])
    @@ -1479,6 +1523,23 @@ +
  • + + skip_checks + + : + + (boolean) + + when true there will be no checks are done for if the player is valid + + (default: false) +
  • + + + + +
  • silent @@ -1505,6 +1566,11 @@ + Usage: +
    -- Unassign a player from the Moderator role
    +Roles.unassign_player(game.player,  'Moderator')
    +
    -- Unassign a player from the Moderator role, even if the player has never been on the map
    +Roles.unassign_player('Cooldude2606',  'Moderator', nil, true)
  • @@ -1512,7 +1578,7 @@
    # - override_player_roles(roles) + override_player_roles([player_name], roles)
    @@ -1530,6 +1596,23 @@ +
  • + + player_name + + : + + (string) + + the player to set the roles for, if not given all roles are overriden + + (optional) +
  • + + + + +
  • roles @@ -1555,6 +1638,14 @@ + Usage: +
    -- Override the roles of a single player, other users are not effected
    +Roles.override_player_roles('Cooldude2606', {'Moderator'})
    +
    -- Override all existing roles, effects all users not just ones listed
    +Roles.override_player_roles{
    +    ['Cooldude2606'] = {'Administrator','Moderator'},
    +    ['arty714'] = {'Administrator','Moderator'},
    +}
  • @@ -1631,6 +1722,9 @@ + Usage: +
    -- Test if a player has a role
    +local has_role = Roles.player_has_role(game.player, 'Moderator')
    @@ -1704,6 +1798,9 @@ + Usage: +
    -- Test if a player has a role
    +local has_flag = Roles.player_has_flag(game.player, 'is_donator')
    @@ -1777,6 +1874,9 @@ + Usage: +
    -- Test if a player has a role
    +local has_flag = Roles.player_has_flag(game.player, 'is_donator')
    @@ -1794,7 +1894,7 @@

    Used to set the role order, higher in the list is better, must be called at least once in config - nb: function also re links parents due to expected position in the config file

    +-- nb: function also re links parents due to expected position in the config file

    @@ -1831,6 +1931,15 @@ + Usage: +
    -- Define which roles are higher than others
    +Roles.define_role_order{
    +    'System',
    +    'Administrator',
    +    'Moderator',
    +    'Donator',
    +    'Guest'
    +}
    @@ -1881,8 +1990,6 @@ (function) the function that is called when roles are assigned - flag param - player - the player that has had they roles changed - flag param - state - the state of the flag, aka if the flag is present @@ -1899,6 +2006,11 @@ + Usage: +
    -- Defineing a flag trigger
    +Roles.define_flag_trigger('is_donator', function(player, state)
    +    player.character_running_speed_modifier = state and 1.5 or 1
    +end)
    @@ -1949,6 +2061,9 @@ + Usage: +
    -- Setting the default role
    +Roles.set_default('Guest')
    @@ -1999,6 +2114,9 @@ + Usage: +
    -- Setting the root role
    +Roles.set_root('System')
    @@ -2073,6 +2191,9 @@ + Usage: +
    -- Defineing a new role
    +local role = Roles.new_role('Moderator', 'Mod')
    @@ -2134,6 +2255,9 @@ + Usage: +
    -- Allow all actions for this role, useful for root like roles
    +role:set_allow_all()
    @@ -2191,6 +2315,12 @@ + Usage: +
    -- Allow some actions for a role
    +role:allow{
    +    'command/kill',
    +    'gui/game settings'
    +}
    @@ -2248,6 +2378,12 @@ + Usage: +
    -- Disalow an action for a role, useful if inherit an action from a parent
    +role:disallow{
    +    'command/kill',
    +    'gui/game settings'
    +}
    @@ -2305,6 +2441,9 @@ + Usage: +
    -- Test if a role is allowed an action
    +local allowed = role:is_allowed('command/kill')
    @@ -2382,6 +2521,9 @@ + Usage: +
    -- Set a flag for a role
    +role:set_flag('is_admin')
    @@ -2416,6 +2558,9 @@ + Usage: +
    -- Remove all flags from a role
    +role:clear_flags()
    @@ -2473,6 +2618,9 @@ + Usage: +
    -- Test if a role has a flag
    +local has_flag = role:has_flag('is_admin')
    @@ -2533,6 +2681,9 @@ + Usage: +
    -- Set a custom tag for this role, other code is required to set the tag
    +role:set_custom_tag('Mod')
    @@ -2590,6 +2741,9 @@ + Usage: +
    -- Set a custom colour for this role, other code is required to use this value
    +role:set_custom_color{ r=255, g=100, b=100}
    @@ -2664,6 +2818,9 @@ + Usage: +
    -- Set the permission group for this role, see permission_groups.lua
    +role:set_permission_group('Admin')
    @@ -2678,7 +2835,7 @@

    Sets the parent for a role, any action not in allow or disallow will be looked for in its parents - nb: this is a recursive action, and changing the allows and disallows will effect all children roles

    +nb: this is a recursive action, and changing the allows and disallows will effect all children roles

    @@ -2722,21 +2879,24 @@ + Usage: +
    -- Set the parent for this role to inherit all actions allowed
    +role:set_parent('Guest')
    - # - Roles._prototype:set_auto_promote_condition(callback) + # + Roles._prototype:set_auto_assign_condition(callback)
    -

    Sets an auto promote condition that is checked every 5 seconds, if true is returned then the player will receive the role - nb: this is one way, failing false after already gaining the role will not revoke the role

    +

    Sets an auto assign condition that is checked every 60 seconds, if true is returned then the player will receive the role +nb: this is one way, failing false after already gaining the role will not revoke the role

    @@ -2780,6 +2940,11 @@ + Usage: +
    -- Give this role to a user if there are admin, ran every 60 seconds
    +role:set_auto_assign_condition(function(player)
    +    return player.admin
    +end)
    @@ -2793,7 +2958,7 @@
    -

    Sets the role to not allow players to have auto promote effect them, useful to keep people locked to a punishment

    +

    Sets the role to not allow players to have auto assign effect them, useful to keep people locked to a role

    @@ -2813,7 +2978,7 @@ (boolean) - when true the players with this role will not be auto promoted + when true the players with this role will not be auto assigned to other roles (default: true) @@ -2838,6 +3003,9 @@ + Usage: +
    -- Make a role stop players from being auto assigned to other roles
    +role:set_block_auto_promote()
    @@ -2930,6 +3098,9 @@ + Usage: +
    -- Assign a player to this role
    +role:add_player(game.player)
    @@ -3019,6 +3190,9 @@ + Usage: +
    -- Unassign a player from this role
    +role:remove_player(game.player)
    @@ -3077,6 +3251,11 @@ + Usage: +
    -- Get all the players with this role
    +local players = role:get_players()
    +
    -- Get all online players with this role
    +local players = role:get_players(true)
    @@ -3134,6 +3313,9 @@ + Usage: +
    -- Print a message to all players with this role
    +role:print('Hello, World!')
    @@ -3152,7 +3334,7 @@ generated by LDoc
    diff --git a/docs/core/Store.html b/docs/core/Store.html index fd876dbc..51907502 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -53,13 +53,13 @@ @@ -88,10 +88,12 @@ + + @@ -100,8 +102,10 @@

    Guis

    @@ -139,7 +143,6 @@

    Configs

    @@ -172,18 +176,13 @@

    Modules

    @@ -1481,7 +1480,7 @@ Store.set(player_scores,game.player,10) generated by LDoc
    diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index 0dbdaafd..f6a07252 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -51,8 +51,10 @@

    Guis

    @@ -62,13 +64,13 @@ @@ -97,10 +99,12 @@ + + @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -224,7 +223,7 @@

    Player-List gui

    Gui Module - Player List - - Adds a player list to show names and play time; also includes action buttons which can apply to players

    + - Adds a player list to show names and play time; also includes action buttons which can preform actions to players

    @@ -259,14 +258,14 @@ utils.event + config.gui.player_list_actions + + + utils.color_presets + + expcore.common - - config.action_buttons - - - resources.color_presets - @@ -288,8 +287,20 @@ - - + + + + + + + + + + + + + +
    Button used to confirm a reason
    player_listRegisters the player listadd_player_baseSet of elements that are used to make up a row of the player table
    add_action_barAdds all the buttons and flows that make up the action bar
    player_list_containerMain player list container for the left flow
    toggle_left_elementButton on the top flow used to toggle the player list container
    @@ -418,6 +429,56 @@ + + + + + + + +
    +
    +
    + # + config.gui.player_list_actions +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.color_presets +
    +
    +
    +
    + + + + + + + + + @@ -443,56 +504,6 @@ - - - - - - -
    -
    -
    -
    - # - config.action_buttons -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - resources.color_presets -
    -
    -
    -
    - - - - - - - - - @@ -587,14 +598,95 @@
    - # - player_list + # + add_player_base
    -

    Registers the player list

    +

    Set of elements that are used to make up a row of the player table

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + add_action_bar +
    +
    +
    +
    + +

    Adds all the buttons and flows that make up the action bar

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + player_list_container +
    +
    +
    +
    + +

    Main player list container for the left flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + toggle_left_element +
    +
    +
    +
    + +

    Button on the top flow used to toggle the player list container

    @@ -626,7 +718,7 @@ generated by LDoc
    diff --git a/docs/guis/Readme.html b/docs/guis/Readme.html new file mode 100644 index 00000000..beecc8d1 --- /dev/null +++ b/docs/guis/Readme.html @@ -0,0 +1,735 @@ + + + + + + + + Readme gui + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    Readme gui

    +

    Gui Module - Readme + - Adds a main gui that contains lots of important information about our server

    +

    + + + + + + + + + + + + + +

    Dependencies

    + + + + + + + + + + + + + + + + + + + +
    expcore.gui
    expcore.roles
    expcore.commands
    utils.event
    utils.game
    + + +

    Elements

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    sub_contentSub content area used within the content areas
    title_tableTable which has a title above it above it
    title_table_scrollScroll to be used with Gui.title_label tables
    welcome_contentContent area for the welcome tab
    rules_contentContent area for the rules tab
    commands_contentContent area for the commands tab
    servers_contentContent area for the servers tab
    backers_contentContent area for the servers tab
    readmeMain readme container for the center flow
    readme_toggleToggle button for the readme gui
    + + +
    + + +

    Dependencies

    +
    +
    +
    +
    + # + expcore.gui +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + expcore.roles +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + expcore.commands +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.event +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.game +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +

    Elements

    +
    +
    +
    +
    + # + sub_content +
    +
    +
    +
    + +

    Sub content area used within the content areas

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + title_table +
    +
    +
    +
    + +

    Table which has a title above it above it

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + title_table_scroll +
    +
    +
    +
    + +

    Scroll to be used with Gui.title_label tables

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + welcome_content +
    +
    +
    +
    + +

    Content area for the welcome tab

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + rules_content +
    +
    +
    +
    + +

    Content area for the rules tab

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + commands_content +
    +
    +
    +
    + +

    Content area for the commands tab

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + servers_content +
    +
    +
    +
    + +

    Content area for the servers tab

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + backers_content +
    +
    +
    +
    + +

    Content area for the servers tab

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + readme +
    +
    +
    +
    + +

    Main readme container for the center flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + readme_toggle +
    +
    +
    +
    + +

    Toggle button for the readme gui

    +

    + + + + + + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index 3de18001..b112fb6a 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -51,8 +51,10 @@

    Guis

    @@ -62,13 +64,13 @@ @@ -97,10 +99,12 @@ + + @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -253,17 +252,17 @@ utils.event - config.rockets + config.gui.rockets - expcore.common - - - resources.color_presets + utils.color_presets modules.control.rockets + + expcore.common + @@ -273,24 +272,32 @@ - - + + - + - - + + - - + + - - + + + + + + + + + +
    zoom_to_mapUsed on the name label to allow zoom to maptoggle_launchButton to toggle the auto launch on a rocket silo
    launch_rocketUsed to launch the rocket, when it is readyButton to remotely launch a rocket from a silo
    toggle_rocketUsed to toggle the auto launch on a rocketsilo_cordsXY cords that allow zoom to map when pressed
    toggle_sectionUsed to toggle the visibility of the different sectionsrocket_entryBase element for each rocket in the progress list
    rocket_infoRegisters the rocket infodata_labelData label which contains a name and a value label pair
    rocket_list_containerMain gui container for the left flow
    toggle_left_elementButton on the top flow used to toggle the container
    @@ -379,8 +386,8 @@
    - # - config.rockets + # + config.gui.rockets
    @@ -404,33 +411,8 @@
    - # - expcore.common -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - resources.color_presets + # + utils.color_presets
    @@ -469,6 +451,31 @@ + + + + + + +
    +
    +
    +
    + # + expcore.common +
    +
    +
    +
    + + + + + + + + + @@ -482,14 +489,14 @@
    - # - zoom_to_map + # + toggle_launch
    -

    Used on the name label to allow zoom to map

    +

    Button to toggle the auto launch on a rocket silo

    @@ -516,7 +523,7 @@
    -

    Used to launch the rocket, when it is ready

    +

    Button to remotely launch a rocket from a silo

    @@ -536,14 +543,14 @@
    - # - toggle_rocket + # + silo_cords
    -

    Used to toggle the auto launch on a rocket

    +

    XY cords that allow zoom to map when pressed

    @@ -563,14 +570,14 @@
    - # - toggle_section + # + rocket_entry
    -

    Used to toggle the visibility of the different sections

    +

    Base element for each rocket in the progress list

    @@ -590,14 +597,68 @@
    - # - rocket_info + # + data_label
    -

    Registers the rocket info

    +

    Data label which contains a name and a value label pair

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + rocket_list_container +
    +
    +
    +
    + +

    Main gui container for the left flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + toggle_left_element +
    +
    +
    +
    + +

    Button on the top flow used to toggle the container

    @@ -629,7 +690,7 @@ generated by LDoc
    diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 5d2fbcd2..3b409eb2 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -51,8 +51,10 @@

    Guis

    @@ -62,13 +64,13 @@ @@ -97,10 +99,12 @@ + + @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -253,14 +252,14 @@ utils.event - expcore.common - - - config.science + config.gui.science modules.control.production + + expcore.common + @@ -282,7 +281,7 @@ - + @@ -372,33 +371,8 @@
    - # - expcore.common -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - config.science + # + config.gui.science
    @@ -437,6 +411,31 @@ + + + + + + +
    +
    +
    +
    + # + expcore.common +
    +
    +
    +
    + + + + + + + + + @@ -531,8 +530,8 @@
    - # - task_list_toggle + # + toggle_left_element
    @@ -570,7 +569,7 @@ generated by LDoc diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index 8e546493..c9d42c26 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -51,8 +51,10 @@

    Guis

    @@ -62,13 +64,13 @@ @@ -97,10 +99,12 @@ + + @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -224,7 +223,7 @@

    Task-List gui

    Gui Module - Task List - - Adds a task list to the game which players can add remove and edit items on

    + - Adds a task list to the game which players can add, remove and edit items on

    @@ -253,14 +252,14 @@
    - - - - + + + +
    Main task list container for the left flow
    task_list_toggletoggle_left_element Button on the top flow used to toggle the task list container
    expcore.roles
    config.tasks
    expcore.commonconfig.gui.tasks
    modules.control.tasks
    expcore.common
    @@ -306,7 +305,7 @@ - + @@ -396,33 +395,8 @@
    - # - config.tasks -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.common + # + config.gui.tasks
    @@ -461,6 +435,31 @@ + + + + + + +
    +
    +
    +
    + # + expcore.common +
    +
    +
    +
    + + + + + + + + + @@ -717,8 +716,8 @@
    - # - task_list_toggle + # + toggle_left_element
    @@ -756,7 +755,7 @@ generated by LDoc diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index 2f4ac049..0eaf7808 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -51,8 +51,10 @@

    Guis

    @@ -62,13 +64,13 @@ @@ -97,10 +99,12 @@ + + @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -262,17 +261,17 @@
    - + - - - - + + + +
    Main task list container for the left flow
    task_list_toggletoggle_left_element Button on the top flow used to toggle the task list container
    expcore.roles
    resources.color_presetsutils.color_presets
    config.warps
    expcore.commonconfig.gui.warps
    modules.control.warps
    expcore.common
    @@ -495,8 +494,8 @@
    - # - resources.color_presets + # + utils.color_presets
    @@ -520,33 +519,8 @@
    - # - config.warps -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.common + # + config.gui.warps
    @@ -585,6 +559,31 @@ + + + + + + +
    +
    +
    +
    + # + expcore.common +
    +
    +
    +
    + + + + + + + + + @@ -961,7 +960,7 @@ generated by LDoc
    diff --git a/docs/guis/server-ups.html b/docs/guis/server-ups.html new file mode 100644 index 00000000..3acdff7b --- /dev/null +++ b/docs/guis/server-ups.html @@ -0,0 +1,444 @@ + + + + + + + + server-ups gui + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    server-ups gui

    +

    Gui Module - Server UPS + - Adds a server ups counter in the top right and a command to toggle is

    +

    + + + + + + + + + + + +
    + +

    Dependencies

    + + + + + + + + + + + + + +
    expcore.gui
    utils.event
    expcore.commands
    + + +

    Elements

    + + + + + + + + +
    server_upsLabel to show the server ups
    + + +

    Commands

    + + + + + + + + +
    server-upsToggles if the server ups is visbile
    + + +
    + + +

    Dependencies

    +
    +
    +
    +
    + # + expcore.gui +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.event +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + expcore.commands +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +

    Elements

    +
    +
    +
    +
    + # + server_ups +
    +
    +
    +
    + +

    Label to show the server ups

    +

    + + + + + + + + + + + + + + +
    +
    +

    Commands

    +
    +
    +
    +
    + # + server-ups +
    +
    +
    +
    + +

    Toggles if the server ups is visbile

    +

    + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + diff --git a/docs/index.html b/docs/index.html index 2b553d42..266d509e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -45,39 +45,39 @@

    Core

    - - + + - - + + + + + + +- Used to simplify gui creation using factory functions called element defines - + +- Permission group making for factorio so you never have to make one by hand again +- Factorio role system to manage custom permissions. - - - -
    CommandsCore Module - Commands - - Factorio command making module that makes commands with better parse and more modularityAsyncCore Module - Async +- An extention of task and token to allow a single require to register and run async functions.
    Common-LibraryCore Module - Common Library - - Adds some commonly used functions used in many modulesCommandsCore Module - Commands +- Factorio command making module that makes commands with better parse and more modularity
    CommonCore Module - Common +- Adds some commonly used functions used in many modules
    Gui Core Module - Gui -- Used to define new gui elements and gui event handlers
    Permissions-GroupsGroups Core Module - Permission Groups - - Permission group making for factorio so you never have to make one by hand again
    Roles Core Module - Roles - - Factorio role system to manage custom permissions.
    Store Core Module - Store - Used to store and watch for updates for values in the global table
    SudoCore Module - Sudo - - An extention of task and token to allow a single require to register and run functions bypassing all permissions.

    Control

    @@ -151,6 +151,10 @@ Sends alert messages to our discord server when certain events are triggered + greetings + Greets players on join + + Pollution-Grading Makes polution look much nice of the map, ie not one big red mess @@ -166,13 +170,22 @@ Spawn-Area Adds a custom spawn area with chests and afk turrets + + Tree-Decon + Makes trees which are marked for decon "decay" quickly to allow faster building +

    Guis

    + - Adds a player list to show names and play time; also includes action buttons which can preform actions to players + + + + @@ -185,9 +198,14 @@ - Adds a science info gui that shows production usage and net for the different science packs as well as an eta + + + + + - Adds a task list to the game which players can add, remove and edit items on @@ -306,14 +324,6 @@ to stop a file from loading add "--" in front of it, remove the "--" to have the file be loaded; config files should be loaded after all modules are loaded; core files should be required by modules and not be present in this list; - - - - @@ -350,11 +360,6 @@ - - - - @@ -367,6 +372,11 @@ see ./expcore/commands.lua for more details + + + + @@ -374,6 +384,34 @@ see ./expcore/commands.lua for more details start with Permission_Groups.new_group('name'); then use either :allow_all() or :disallow_all() to set the default for non specified actions; then use :allow{} and :disallow{} to specify certain actions to allow/disallow + + + + + + + + + + + + + + + + + + + + + + + + @@ -392,18 +430,6 @@ see ./expcore/commands.lua for more details - - - - - - - - - - - - @@ -412,17 +438,9 @@ see ./expcore/commands.lua for more details - - - - - - - -
    Player-List Gui Module - Player List - - Adds a player list to show names and play time; also includes action buttons which can apply to players
    ReadmeGui Module - Readme + - Adds a main gui that contains lots of important information about our server
    Rocket-Info
    server-upsGui Module - Server UPS + - Adds a server ups counter in the top right and a command to toggle is
    Task-List Gui Module - Task List - - Adds a task list to the game which players can add remove and edit items on
    Warps-List
    Player-ListConfig for the different action buttons that show on the player list; - each button has the button define(s) given along side an auth function, and optional reason callback; - if a reason callback is used then Store.set(action_name_store,player.name,'BUTTON_NAME') should be called during on_click; - buttons can be removed from the gui by commenting them out of the config at the bottom of this file; - the key used for the name of the button is the permission name used by the role system;
    Advanced-Start
    Commands-Auth-Roles This will make commands only work if the role has been allowed it in the role config
    Commands-Auth-Runtime-DisableThis config for command auth allows commands to be globally enabled and disabled during runtime; - this config adds Commands.disable and Commands.enable to enable and disable commands for all users
    Commands-Parse
    Commands-Parse-Roles Adds some parse functions that can be used with the role system
    Commands-Auth-Runtime-DisableThis config for command auth allows commands to be globally enabled and disabled during runtime; + this config adds Commands.disable and Commands.enable to enable and disable commands for all users
    Permission-Groups
    RolesThis is the main config file for the role system; file includes defines for roles and role flags and default values
    Player-ListConfig for the different action buttons that show on the player list; + each button has the button define(s) given along side an auth function, and optional reason callback; + if a reason callback is used then Store.set(action_name_store,player.name,'BUTTON_NAME') should be called during on_click; + buttons can be removed from the gui by commenting them out of the config at the bottom of this file; + the key used for the name of the button is the permission name used by the role system;
    RocketsThis file controls what will show in each section of the rocket info gui
    ScienceConfig file for the science info gui
    TasksConfig file for the tasks gui
    WarpsThis file contains all the different settings for the warp system and gui
    Pollution-Grading Config file for the repair command
    RocketsThis file controls what will show in each section of the rocket info gui
    RolesThis is the main config file for the role system; file includes defines for roles and role flags and default values
    ScienceConfig file for the science info gui
    Scorched-Earth This file controls the placement/degrading of tiles as players build and walk
    Used to config the spawn generation settings yes there is alot here i know just ignore the long tables at the end (they were generated with a command)
    TasksConfig file for the tasks gui
    Warnings Config file for the warning system, this is very similar to reports but is for the use of moderators rather than normal users.
    WarpsThis file contains all the different settings for the warp system and gui

    Modules

    @@ -434,21 +452,20 @@ see ./expcore/commands.lua for more details this file is the landing point for all scenarios please DO NOT edit directly, further comments are to aid development - - + + - - + - + + - - + + @@ -459,30 +476,9 @@ see ./expcore/commands.lua for more details - - - - - - - - - - - - - - - - - - - -
    utils.alien_evolution_progressinfo - Original (javascript) version: https://hastebin.com/udakacavap.js - Can be tested against: https://wiki.factorio.com/Enemies#Spawn_chances_by_evolution_factormodules.addons.station-auto-nameLuaPlayerBuiltEntityEventFilters +Events.set_event_filter(defines.events.on_built_entity, {{filter = "name", name = "fast-inserter"}})
    utils.coreThis file contains core utilities used by the redmew scenario.overrides.debug
    utils.debugoverrides.mathTakes two points and calculates the slope of a line
    utils.dump_envA small debugging tool that writes the contents of _ENV to a file when the game loads.overrides.tableSearches a table to remove a specific element without an index
    utils.event Do not use this function, use Event.add instead as it has safety checks.
    utils.mathTakes two points and calculates the slope of a line
    utils.recipe_lockerA module to prevent recipes from being unlocked by research.
    utils.state_machineThis module provides a classical mealy/moore state machine.
    utils.tableSearches a table to remove a specific element without an index
    utils.task Threading simulation module Task.sleep()
    utils.timestampsource https://github.com/daurnimator/luatz/blob/master/luatz/timetable.lua - edited down to just what is needed.

    Topics

    @@ -511,7 +507,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/Gui.html b/docs/modules/Gui.html index 7f2d9a40..4ff9023c 100644 --- a/docs/modules/Gui.html +++ b/docs/modules/Gui.html @@ -41,7 +41,16 @@ @@ -51,18 +60,13 @@ @@ -70,12 +74,26 @@ + + @@ -90,10 +108,26 @@ + + + + + + @@ -126,36 +160,9 @@ - - @@ -201,7 +209,16 @@ @@ -221,7 +238,8 @@

    Gui module

    -

    Core Module - Gui

    +

    Core Module - Gui +- Gui defines that are used internally by the gui system

    @@ -236,17 +254,329 @@ -

    Functions

    +

    Dependencies

    - - + - - + + + + + + + + + +
    on_custom_event(handler)Adds a custom event handler, replace with the name of the eventutils.event
    set_custom_property(value)Sets a new value for a property, triggers setter method if provided, replace with property namemod-gui
    utils.event
    mod-gui
    + + +

    Tables

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    eventsString indexed table used to avoid conflict with custom event names, similar to how defines.events works
    definesUid indexed array that stores all the factory functions that were defined, no new values will be added during runtime
    core_definesAn string indexed table of all the defines which are used by the core of the gui system, used for internal refrence
    file_pathsUsed to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debuging
    debug_infoUsed to store extra infomation about elements as they get defined such as the params used and event handlers registered to them
    _prototype_elementThe prototype used to store the functions of an element define
    _mt_elementThe prototype metatable applied to new element defines
    + + +

    Fields

    + + + + + + + + +
    uidThe current highest uid that is being used by a define, will not increase during runtime
    + + +

    Core Defines

    + + + + + + + + + + + + + + + + +
    hide_top_flowButton which toggles the top flow elements, version which shows inside the top flow when top flow is visible
    show_top_flowButton which toggles the top flow elements, version which shows inside the left flow when top flow is hidden
    hide_left_flowButton which hides the elements in the left flow, shows inside the left flow when frames are visible
    + + +

    Defines

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    alignmentDraw a flow used to align its child elements, default is right align
    scroll_tableDraw a scroll pane that has a table inside of it
    headerUsed to add a frame with the header style, has the option for a right alignment flow for buttons
    footerUsed to add a frame with the footer style, has the option for a right alignment flow for buttons
    containerUsed for left frames to give them a nice boarder
    barUsed to make a solid white bar in a gui
    centered_labelUsed to make a label which is centered and of a certian size
    title_labelUsed to make a title which has two bars on either side
    + + +

    Helper Functions

    + + + + + + + + + + + + + + + + + + + + + + + + +
    get_player_from_element(element)Get the player that owns a gui element
    toggle_enabled_state(element[, state])Will toggle the enabled state of an element or set it to the one given
    toggle_visible_state(element[, state])Will toggle the visible state of an element or set it to the one given
    destroy_if_valid(element)Destory a gui element without causing any errors, often because the element was already removed
    sprite_style(size[, padding=-2][, style])Returns a table to be used as the style for a sprite buttons, produces a sqaure button
    + + +

    Left Flow

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    left_elementsContains the uids of the elements that will shown on the left flow and their join functions
    get_left_flow(player)Gets the flow refered to as the left flow, each player has one left flow
    Gui._prototype_element:add_to_left_flow([open_on_join])Sets an element define to be drawn to the left flow when a player joins, includes optional check
    left_toolbar_button(sprite, tooltip, element_define[, authenticator])Creates a button on the top flow which will toggle the given element define, the define must exist in the left flow
    draw_left_flow(player)Draw all the left elements onto the left flow, internal use only with on join
    update_left_flow(player)Update the visible state of the hide button, can be used to check if any frames are visible
    hide_left_flow(player)Hides all left elements for a player
    get_left_element(player, element_define)Get the element define that is in the left flow, use in events without an element refrence
    toggle_left_element(player, element_define[, state])Toggles the visible state of a left element for a given player, can be used to set the visible state
    + + +

    Element Define

    + + + + + + + + + + + + + + + + + + + + +
    element(element_define)Used to define new elements for your gui, can be used like LuaGuiElement.add or a custom function
    Gui._prototype_element:style(style_define)Used to extent your element define with a style factory, this style will be applied to your element when created, can also be a custom function
    Gui._prototype_element:on_custom_event(event_name, handler)Set the handler which will be called for a custom event, only one handler can be used per event per element
    Gui._prototype_element:raise_custom_event(event)Raise the handler which is attached to an event; external use should be limited to custom events
    + + +

    Element Events

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Gui._prototype_element.on_openCalled when the player opens a GUI.
    Gui._prototype_element.on_closeCalled when the player closes the GUI they have open.
    Gui._prototype_element.on_clickCalled when LuaGuiElement is clicked.
    Gui._prototype_element.on_confirmedCalled when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.
    Gui._prototype_element.on_checked_changedCalled when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).
    Gui._prototype_element.on_elem_changedCalled when LuaGuiElement element value is changed (related to choose element buttons).
    Gui._prototype_element.on_location_changedCalled when LuaGuiElement element location is changed (related to frames in player.gui.screen).
    Gui._prototype_element.on_tab_changedCalled when LuaGuiElement selected tab is changed (related to tabbed-panes).
    Gui._prototype_element.on_selection_changedCalled when LuaGuiElement selection state is changed (related to drop-downs and listboxes).
    Gui._prototype_element.on_switch_changedCalled when LuaGuiElement switch state is changed (related to switches).
    Gui._prototype_element.on_text_changedCalled when LuaGuiElement text is changed by the player.
    Gui._prototype_element.on_value_changedCalled when LuaGuiElement slider value is changed (related to the slider element).
    + + +

    Top Flow

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    top_elementsContains the uids of the elements that will shown on the top flow and their auth functions
    top_flow_button_styleThe style that should be used for buttons on the top flow
    top_flow_button_visible_styleThe style that should be used for buttons on the top flow when their flow is visible
    get_top_flow(player)Gets the flow refered to as the top flow, each player has one top flow
    Gui._prototype_element:add_to_top_flow([authenticator])Sets an element define to be drawn to the top flow when a player joins, includes optional authenticator
    update_top_flow(player)Updates the visible state of all the elements on the players top flow, uses authenticator
    toggle_top_flow(player[, state])Toggles the visible state of all the elements on a players top flow, effects all elements
    get_top_element(player, element_define)Get the element define that is in the top flow, use in events without an element refrence
    toolbar_button(sprite, tooltip[, authenticator])Creates a button on the top flow with consistent styling
    toolbar_button_style(button, state)Styles a top flow button depending on the state given
    @@ -255,56 +585,23 @@
    -

    Functions

    +

    Dependencies

    - # - on_custom_event(handler) + # + utils.event
    -

    Adds a custom event handler, replace with the name of the event

    -

    - Parameters: - -
      - - - - - -
    • - - handler - - : - - (function) - - the function which will recive the event - -
    • - - -
    - - Returns: -
      -
    • - (GuiConcept) - to allow chaing of functions -[[@usage -
    • -
    @@ -318,14 +615,1256 @@
    - # - set_custom_property(value) + # + mod-gui
    -

    Sets a new value for a property, triggers setter method if provided, replace with property name

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + utils.event +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    +
    + # + mod-gui +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +

    Tables

    +
    +
    +
    +
    + # + events +
    +
    +
    +
    + +

    String indexed table used to avoid conflict with custom event names, similar to how defines.events works

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + defines +
    +
    +
    +
    + +

    Uid indexed array that stores all the factory functions that were defined, no new values will be added during runtime

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + core_defines +
    +
    +
    +
    + +

    An string indexed table of all the defines which are used by the core of the gui system, used for internal refrence

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + file_paths +
    +
    +
    +
    + +

    Used to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debuging

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + debug_info +
    +
    +
    +
    + +

    Used to store extra infomation about elements as they get defined such as the params used and event handlers registered to them

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + _prototype_element +
    +
    +
    +
    + +

    The prototype used to store the functions of an element define

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + _mt_element +
    +
    +
    +
    + +

    The prototype metatable applied to new element defines

    +

    + + + Fields: + +
      + + + + + +
    • + + __call + + + + + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +

    Fields

    +
    +
    +
    +
    + # + uid +
    +
    +
    +
    + +

    The current highest uid that is being used by a define, will not increase during runtime

    +

    + + + +
      + + + + + +
    • + + uid + + + + + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +

    Core Defines

    +
    +
    +
    +
    + # + hide_top_flow +
    +
    +
    +
    + +

    Button which toggles the top flow elements, version which shows inside the top flow when top flow is visible

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + show_top_flow +
    +
    +
    +
    + +

    Button which toggles the top flow elements, version which shows inside the left flow when top flow is hidden

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + hide_left_flow +
    +
    +
    +
    + +

    Button which hides the elements in the left flow, shows inside the left flow when frames are visible

    +

    + + + + + + + + + + + + + + +
    +
    +

    Defines

    +
    +
    +
    +
    + # + alignment +
    +
    +
    +
    + +

    Draw a flow used to align its child elements, default is right align

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the alignment will be added + +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the alignment flow which is added + + (default: 'alignment') +
    • + + + + + +
    • + + horizontal_align + + : + + (string) + + the horizontal alignment of the elements in the flow + + (default: 'right') +
    • + + + + + +
    • + + vertical_align + + : + + (string) + + the vertical alignment of the elements in the flow + + (default: 'center') +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a right align flow
    +local alignment = Gui.alignment(element,'example_right_alignment')
    +
    -- Adding a horizontal center and top align flow
    +local alignment = Gui.alignment(element,'example_center_top_alignment','center','top')
    + + +
    +
    +
    +
    + # + scroll_table +
    +
    +
    +
    + +

    Draw a scroll pane that has a table inside of it

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the scroll table will be added + +
    • + + + + + +
    • + + height + + : + + (number) + + the maximum height for the scroll pane + +
    • + + + + + +
    • + + column_count + + : + + (number) + + the number of columns that the table will have + +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the scroll pane that is added, the table is always called "table" + + (default: 'scroll') +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a scroll table with max height of 200 and column count of 3
    +local scroll_table = Gui.scroll_table(element,200,3)
    + + +
    +
    +
    +
    + # + header +
    +
    +
    +
    + +

    Used to add a frame with the header style, has the option for a right alignment flow for buttons

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the header will be added + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the header + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the header + + (optional) +
    • + + + + + +
    • + + add_alignment + + : + + (boolean) + + when true an alignment flow will be added to the header + + (default: false) +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the header that is being added, the alignment is always called "alignment" + + (default: 'header') +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a custom header with a label
    +local header = Gui.header(
    +    element,
    +    'Example Caption',
    +    'Example Tooltip'
    +)
    + + +
    +
    +
    +
    + # + footer +
    +
    +
    +
    + +

    Used to add a frame with the footer style, has the option for a right alignment flow for buttons

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the footer will be added + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the footer + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the footer + + (optional) +
    • + + + + + +
    • + + add_alignment + + : + + (boolean) + + when true an alignment flow will be added to the footer + + (default: false) +
    • + + + + + +
    • + + name + + : + + (string) + + the name of the footer that is being added, the alignment is always called "alignment" + + (default: 'footer') +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a custom footer with a label
    +local footer = Gui.footer(
    +    element,
    +    'Example Caption',
    +    'Example Tooltip'
    +)
    + + +
    +
    +
    +
    + # + container +
    +
    +
    +
    + +

    Used for left frames to give them a nice boarder

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the container will be added + +
    • + + + + + +
    • + + name + + : + + (string) + + the name that you want to give to the outer frame, often just event_trigger + +
    • + + + + + +
    • + + width + + : + + (number) + + the minimal width that the frame will have + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a container as a base
    +local container = Gui.container(parent,'my_container',200)
    + + +
    +
    +
    +
    + # + bar +
    +
    +
    +
    + +

    Used to make a solid white bar in a gui

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the bar will be added + +
    • + + + + + +
    • + + width + + : + + (number) + + the width of the bar that will be made, if not given bar will strech to fill the parent + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a bar to a gui
    +local bar = Gui.bar(parent, 100)
    + + +
    +
    +
    +
    + # + centered_label +
    +
    +
    +
    + +

    Used to make a label which is centered and of a certian size

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the label will be added + +
    • + + + + + +
    • + + width + + : + + (number) + + the width of the label, must be given in order to center the caption + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the label + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the label + + (optional) +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a centered label
    +local label = Gui.centered_label(parent, 100, 'This is centered')
    + + +
    +
    +
    +
    + # + title_label +
    +
    +
    +
    + +

    Used to make a title which has two bars on either side

    +

    + + + Properties / Events: + +
      + + + + + +
    • + + parent + + : + + (LuaGuiElement) + + the parent element to which the label will be added + +
    • + + + + + +
    • + + width + + : + + (number) + + the width of the first bar, this can be used to position the label + +
    • + + + + + +
    • + + caption + + : + + (string or LocalizedString) + + the caption that will be shown on the label + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that will be shown on the label + + (optional) +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Adding a centered label
    +local label = Gui.centered_label(parent, 100, 'This is centered')
    + + +
    +
    +

    Helper Functions

    +
    +
    +
    +
    + # + get_player_from_element(element) +
    +
    +
    +
    + +

    Get the player that owns a gui element

    @@ -339,13 +1878,13 @@
  • - value + element : - (any) + (LuaGuiElement) - the value that you want to set for this property + the element to get the owner of
  • @@ -358,9 +1897,8 @@ Returns:
    • - (GuiConcept) - to allow chaing of functions -[[@usage + (LuaPlayer) + the player that owns this element
    @@ -370,6 +1908,2404 @@ + Usage: +
    -- Geting the owner of an element
    +local player = Gui.get_player_from_element(element)
    + + +
    +
    +
    +
    + # + toggle_enabled_state(element[, state]) +
    +
    +
    +
    + +

    Will toggle the enabled state of an element or set it to the one given

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element to toggle/set the enabled state of + +
    • + + + + + +
    • + + state + + : + + (boolean) + + with given will set the state, else state will be toggled + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new enabled state that the element has +
    • +
    + + + + + + + + Usage: +
    -- Toggling the the enabled state
    +local new_enabled_state = Gui.toggle_enabled_state(element)
    + + +
    +
    +
    +
    + # + toggle_visible_state(element[, state]) +
    +
    +
    +
    + +

    Will toggle the visible state of an element or set it to the one given

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element to toggle/set the visible state of + +
    • + + + + + +
    • + + state + + : + + (boolean) + + with given will set the state, else state will be toggled + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new visible state that the element has +
    • +
    + + + + + + + + Usage: +
    -- Toggling the the visible state
    +local new_visible_state = Gui.toggle_visible_state(element)
    + + +
    +
    +
    +
    + # + destroy_if_valid(element) +
    +
    +
    +
    + +

    Destory a gui element without causing any errors, often because the element was already removed

    +

    + + + Parameters: + +
      + + + + + +
    • + + element + + : + + (LuaGuiElement) + + the element that you want to remove + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if the element was valid and has been removed +
    • +
    + + + + + + + + Usage: +
    -- Remove a child element if it exists
    +Gui.destroy_if_valid(element[child_name])
    + + +
    +
    +
    +
    + # + sprite_style(size[, padding=-2][, style]) +
    +
    +
    +
    + +

    Returns a table to be used as the style for a sprite buttons, produces a sqaure button

    +

    + + + Parameters: + +
      + + + + + +
    • + + size + + : + + (number) + + the size that you want the button to be + +
    • + + + + + +
    • + + padding + + : + + (number) + + the padding that you want on the sprite + + (default: -2) +
    • + + + + + +
    • + + style + + : + + (table) + + any extra style settings that you want to have + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the style table to be used with element_define:style() +
    • +
    + + + + + + + + Usage: +
    -- Adding a sprite button with size 20
    +local button =
    +Gui.element{
    +    type = 'sprite-button',
    +    sprite = 'entity/inserter'
    +}
    +:style(Gui.sprite_style(20))
    + + +
    +
    +

    Left Flow

    +
    +
    +
    +
    + # + left_elements +
    +
    +
    +
    + +

    Contains the uids of the elements that will shown on the left flow and their join functions

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + get_left_flow(player) +
    +
    +
    +
    + +

    Gets the flow refered to as the left flow, each player has one left flow

    +

    (player)

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to get the left flow for + +
    • + + +
    + + + + + Returns: + + + + + + + + + Usage: +
    -- Geting your left flow
    +local left_flow = Gui.get_left_flow(game.player)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:add_to_left_flow([open_on_join]) +
    +
    +
    +
    + +

    Sets an element define to be drawn to the left flow when a player joins, includes optional check

    +

    + + + Parameters: + +
      + + + + + +
    • + + open_on_join + + : + + (boolean or function) + + called during first darw to decide if the element should be visible + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the new element define that is used to register events to this element +
    • +
    + + + + + + + + Usage: +
    -- Adding the example button
    +example_flow_with_button:add_to_left_flow(true)
    + + +
    +
    +
    +
    + # + left_toolbar_button(sprite, tooltip, element_define[, authenticator]) +
    +
    +
    +
    + +

    Creates a button on the top flow which will toggle the given element define, the define must exist in the left flow

    +

    + + + Parameters: + +
      + + + + + +
    • + + sprite + + : + + (string) + + the sprite that you want to use on the button + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that you want the button to have + +
    • + + + + + +
    • + + element_define + + : + + (table) + + the element define that you want to have toggled by this button, define must exist on the left flow + +
    • + + + + + +
    • + + authenticator + + : + + (function) + + used to decide if the button should be visible to a player + + (optional) +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Add a button to toggle a left element
    +local toolbar_button =
    +Gui.left_toolbar_button('entity/inserter', 'Nothing to see here', example_flow_with_button, function(player)
    +    return player.admin
    +end)
    + + +
    +
    +
    +
    + # + draw_left_flow(player) +
    +
    +
    +
    + +

    Draw all the left elements onto the left flow, internal use only with on join

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to draw the elements for + +
    • + + +
    + + + + + + + + + + + + Usage: +
     Draw all the left elements
    +Gui.draw_left_flow(player)
    + + +
    +
    +
    +
    + # + update_left_flow(player) +
    +
    +
    +
    + +

    Update the visible state of the hide button, can be used to check if any frames are visible

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player to update the left flow for + +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + true if any left element is visible +
    • +
    + + + + + + + + Usage: +
    -- Check if any left elements are visible
    +local visible = Gui.update_left_flow(player)
    + + +
    +
    +
    +
    + # + hide_left_flow(player) +
    +
    +
    +
    + +

    Hides all left elements for a player

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player to hide the elements for + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Hide your left elements
    +Gui.hide_left_flow(game.player)
    + + +
    +
    +
    +
    + # + get_left_element(player, element_define) +
    +
    +
    +
    + +

    Get the element define that is in the left flow, use in events without an element refrence

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to get the element for + +
    • + + + + + +
    • + + element_define + + : + + (table) + + the element that you want to get + +
    • + + +
    + + + + + Returns: +
      +
    • + (LuaGuiElement) + the gui element linked to this define for this player +
    • +
    + + + + + + + + Usage: +
    -- Get your left element
    +local frame = Gui.get_left_element(game.player, example_flow_with_button)
    + + +
    +
    +
    +
    + # + toggle_left_element(player, element_define[, state]) +
    +
    +
    +
    + +

    Toggles the visible state of a left element for a given player, can be used to set the visible state

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to toggle the element for + +
    • + + + + + +
    • + + element_define + + : + + (table) + + the element that you want to toggle + +
    • + + + + + +
    • + + state + + : + + (boolean) + + with given will set the state, else state will be toggled + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new visible state of the element +
    • +
    + + + + + + + + Usage: +
    -- Toggle your example button
    +Gui.toggle_top_flow(game.player, example_flow_with_button)
    +
    -- Show your example button
    +Gui.toggle_top_flow(game.player, example_flow_with_button, true)
    + + +
    +
    +

    Element Define

    +
    +
    +
    +
    + # + element(element_define) +
    +
    +
    +
    + +

    Used to define new elements for your gui, can be used like LuaGuiElement.add or a custom function

    +

    + + + Parameters: + +
      + + + + + +
    • + + element_define + + : + + (table or function) + + the define information for the gui element, same data as LuaGuiElement.add, or a custom function may be used + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the new element define, this can be considered a factory for the element which can be called to draw the element to any other element +
    • +
    + + + + + + + + Usage: +
    -- Using element defines like LuaGuiElement.add
    +-- This returns a factory function to draw a button with the caption "Example Button"
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button'
    +}
    +
    -- Using element defines with a custom factory function
    +-- This method can be used if you still want to be able register event handlers but it is too complex to be compatible with LuaGuiElement.add
    +local example_flow_with_button =
    +Gui.element(function(event_trigger,parent,...)
    +    -- ... shows that all other arguments from the factory call are passed to this function
    +    -- parent is the element which was passed to the factory function where you should add your new element
    +    -- here we are adding a flow which we will then later add a button to
    +    local flow =
    +    parent.add{
    +        name = 'example_flow',
    +        type = 'flow'
    +    }
    +
    +    -- event_trigger should be the name of any elements you want to trigger your event handlers, such as on_click or on_state_changed
    +    -- now we add the button to the flow that we created earlier
    +    local element =
    +    flow.add{
    +        name = event_trigger,
    +        type = 'button',
    +        caption = 'Example Button'
    +    }
    +
    +    -- you must return your new element, this is so styles can be applied and returned to the caller
    +    -- you may return any of your elements that you add, consider the context in which it will be used for what should be returned
    +    return element
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:style(style_define) +
    +
    +
    +
    + +

    Used to extent your element define with a style factory, this style will be applied to your element when created, can also be a custom function

    +

    + + + Parameters: + +
      + + + + + +
    • + + style_define + + : + + (table or function) + + style table where each key and value pair is treated like LuaGuiElement.style[key] = value, a custom function can be used + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the element define is returned to allow for event handlers to be registered +
    • +
    + + + + + + + + Usage: +
    -- Using the table method of setting the style
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button',
    +    style = 'forward_button' -- factorio styles can be applied here
    +}
    +:style{
    +    height = 25, -- same as element.style.height = 25
    +    width = 100 -- same as element.style.width = 25
    +}
    +
    -- Using the function method to set the style
    +-- Use this method if your style is dynamic and depends on other factors
    +local example_button =
    +Gui.element{
    +    type = 'button',
    +    caption = 'Example Button',
    +    style = 'forward_button' -- factorio styles can be applied here
    +}
    +:style(function(style,element,...)
    +    -- style is the current style object for the elemenent
    +    -- element is the element that is being changed
    +    -- ... shows that all other arguments from the factory call are passed to this function
    +    local player = game.players[element.player_index]
    +    style.height = 25
    +    style.width = 100
    +    style.font_color = player.color
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:on_custom_event(event_name, handler) +
    +
    +
    +
    + +

    Set the handler which will be called for a custom event, only one handler can be used per event per element

    +

    + + + Parameters: + +
      + + + + + +
    • + + event_name + + : + + (string) + + the name of the event you want to handler to be called on, often from Gui.events + +
    • + + + + + +
    • + + handler + + : + + (function) + + the handler that you want to be called when the event is raised + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the element define so more handleres can be registered +
    • +
    + + + + + + + + Usage: +
    -- Register a handler to "my_custom_event" for this element
    +element_deinfe:on_custom_event('my_custom_event', function(event)
    +    event.player.print(player.name)
    +end)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:raise_custom_event(event) +
    +
    +
    +
    + +

    Raise the handler which is attached to an event; external use should be limited to custom events

    +

    + + + Parameters: + +
      + + + + + +
    • + + event + + : + + (table) + + the event table passed to the handler, must contain fields: name, element + +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the element define so more events can be raised +
    • +
    + + + + + + + + Usage: +
     Raising a custom event
    +element_define:raise_custom_event{
    +    name = 'my_custom_event',
    +    element = element
    +}
    + + +
    +
    +

    Element Events

    +
    +
    +
    +
    + # + Gui._prototype_element.on_open +
    +
    +
    +
    + +

    Called when the player opens a GUI.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_close +
    +
    +
    +
    + +

    Called when the player closes the GUI they have open.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_click +
    +
    +
    +
    + +

    Called when LuaGuiElement is clicked.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_confirmed +
    +
    +
    +
    + +

    Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_checked_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_elem_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement element value is changed (related to choose element buttons).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_location_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement element location is changed (related to frames in player.gui.screen).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_tab_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement selected tab is changed (related to tabbed-panes).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_selection_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_switch_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement switch state is changed (related to switches).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_text_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement text is changed by the player.

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Gui._prototype_element.on_value_changed +
    +
    +
    +
    + +

    Called when LuaGuiElement slider value is changed (related to the slider element).

    +

    + + + +
      + + + + + +
    • + + handler + + : + + (function) + + the event handler which will be called + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +

    Top Flow

    +
    +
    +
    +
    + # + top_elements +
    +
    +
    +
    + +

    Contains the uids of the elements that will shown on the top flow and their auth functions

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + top_flow_button_style +
    +
    +
    +
    + +

    The style that should be used for buttons on the top flow

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + top_flow_button_visible_style +
    +
    +
    +
    + +

    The style that should be used for buttons on the top flow when their flow is visible

    +

    + + + + + + + + + + + + + + +
    +
    +
    +
    + # + get_top_flow(player) +
    +
    +
    +
    + +

    Gets the flow refered to as the top flow, each player has one top flow

    +

    (player)

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to get the flow for + +
    • + + +
    + + + + + Returns: + + + + + + + + + Usage: +
    -- Geting your top flow
    +local top_flow = Gui.get_top_flow(game.player)
    + + +
    +
    +
    +
    + # + Gui._prototype_element:add_to_top_flow([authenticator]) +
    +
    +
    +
    + +

    Sets an element define to be drawn to the top flow when a player joins, includes optional authenticator

    +

    + + + Parameters: + +
      + + + + + +
    • + + authenticator + + : + + (function) + + called during toggle or update to decide weather the element should be visible + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (table) + the new element define to allow event handlers to be registered +
    • +
    + + + + + + + + Usage: +
    -- Adding an element to the top flow on join
    +example_button:add_to_top_flow(function(player)
    +    -- example button will only be shown if the player is an admin
    +    -- note button will not update its state when player.admin is changed Gui.update_top_flow must be called for this
    +    return player.admin
    +end)
    + + +
    +
    +
    +
    + # + update_top_flow(player) +
    +
    +
    +
    + +

    Updates the visible state of all the elements on the players top flow, uses authenticator

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to update the top flow for + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Update your top flow
    +Gui.update_top_flow(game.player)
    + + +
    +
    +
    +
    + # + toggle_top_flow(player[, state]) +
    +
    +
    +
    + +

    Toggles the visible state of all the elements on a players top flow, effects all elements

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to toggle the top flow for + +
    • + + + + + +
    • + + state + + : + + (boolean) + + if given then the state will be set to this + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (boolean) + the new visible state of the top flow +
    • +
    + + + + + + + + Usage: +
    -- Toggle your flow
    +Gui.toggle_top_flow(game.player)
    +
    -- Open your top flow
    +Gui.toggle_top_flow(game.player,true)
    + + +
    +
    +
    +
    + # + get_top_element(player, element_define) +
    +
    +
    +
    + +

    Get the element define that is in the top flow, use in events without an element refrence

    +

    + + + Parameters: + +
      + + + + + +
    • + + player + + : + + (LuaPlayer) + + the player that you want to get the element for + +
    • + + + + + +
    • + + element_define + + : + + (table) + + the element that you want to get + +
    • + + +
    + + + + + Returns: +
      +
    • + (LuaGuiElement) + the gui element linked to this define for this player +
    • +
    + + + + + + + + Usage: +
    -- Get your top element
    +local button = Gui.get_top_element(game.player, example_button)
    + + +
    +
    +
    +
    + # + toolbar_button(sprite, tooltip[, authenticator]) +
    +
    +
    +
    + +

    Creates a button on the top flow with consistent styling

    +

    + + + Parameters: + +
      + + + + + +
    • + + sprite + + : + + (string) + + the sprite that you want to use on the button + +
    • + + + + + +
    • + + tooltip + + : + + (string or LocalizedString) + + the tooltip that you want the button to have + +
    • + + + + + +
    • + + authenticator + + : + + (function) + + used to decide if the button should be visible to a player + + (optional) +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Add a button to the toolbar
    +local toolbar_button =
    +Gui.left_toolbar_button('entity/inserter', 'Nothing to see here', function(player)
    +    return player.admin
    +end)
    + + +
    +
    +
    +
    + # + toolbar_button_style(button, state) +
    +
    +
    +
    + +

    Styles a top flow button depending on the state given

    +

    + + + Parameters: + +
      + + + + + +
    • + + button + + : + + (LuaGuiElement) + + the button element to style + +
    • + + + + + +
    • + + state + + : + + (boolean) + + The state the button is in + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Sets the button to the visible style
    +Gui.toolbar_button_style(button, true)
    +
    -- Sets the button to the hidden style
    +Gui.toolbar_button_style(button, false)
    @@ -388,7 +4324,7 @@ generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index 4fc84050..3542b831 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,18 +50,13 @@

    Modules

    @@ -69,13 +64,13 @@ @@ -104,10 +99,12 @@ + + @@ -116,8 +113,10 @@

    Guis

    @@ -155,7 +154,6 @@

    Configs

    @@ -244,12 +243,6 @@ - utils.debug - - - expcore.common.ext_require - - config._file_loader @@ -264,56 +257,6 @@
    - # - utils.debug -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - # - expcore.common.ext_require -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    -
    -
    -
    # config._file_loader
    @@ -351,7 +294,7 @@ generated by LDoc diff --git a/docs/modules/modules.addons.station-auto-name.html b/docs/modules/modules.addons.station-auto-name.html new file mode 100644 index 00000000..e5d0e142 --- /dev/null +++ b/docs/modules/modules.addons.station-auto-name.html @@ -0,0 +1,300 @@ + + + + + + + + modules.addons.station-auto-name module + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    modules.addons.station-auto-name module

    +

    LuaPlayerBuiltEntityEventFilters +Events.set_event_filter(defines.events.on_built_entity, {{filter = "name", name = "fast-inserter"}})

    +

    + + + + + + + + + + + + + +

    Dependencies

    + + + + + + + +
    utils.event
    + + +
    + + +

    Dependencies

    +
    +
    +
    +
    + # + utils.event +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    + + + +
    +
    +
    + + + + diff --git a/docs/modules/overrides.debug.html b/docs/modules/overrides.debug.html new file mode 100644 index 00000000..3e5221fc --- /dev/null +++ b/docs/modules/overrides.debug.html @@ -0,0 +1,661 @@ + + + + + + + + overrides.debug module + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    overrides.debug module

    +

    +

    + + + + + + + + + + + + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Debug.print(message, trace_levels)Shows the given message if debug is enabled.
    Debug.get_meta_value(object, key)Returns the value of the key inside the object + or 'InvalidLuaObject' if the LuaObject is invalid.
    Debug.object_type(object)Returns the Lua data type or the factorio LuaObject type + or 'NoHelpLuaObject' if the LuaObject does not have a help function + or 'InvalidLuaObject' if the LuaObject is invalid.
    Debug.print_position(position, message)Shows the given message if debug is on.
    Debug.cheat(callback)Executes the given callback if cheating is enabled.
    Debug.is_closure(func)Returns true if the function is a closure, false otherwise.
    + + +
    + + +

    Functions

    +
    +
    +
    +
    + # + Debug.print(message, trace_levels) +
    +
    +
    +
    + +

    Shows the given message if debug is enabled.

    +

    Uses serpent to print non scalars.

    + + + Parameters: + +
      + + + + + +
    • + + message + + : + + + + +
    • + + + + + +
    • + + trace_levels + + : + + + levels of stack trace to give, defaults to 1 level if nil + +
    • + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + # + Debug.get_meta_value(object, key) +
    +
    +
    +
    + +

    Returns the value of the key inside the object + or 'InvalidLuaObject' if the LuaObject is invalid.

    +

    + or 'InvalidLuaObjectKey' if the LuaObject does not have an entry at that key

    + + + Parameters: + +
    +
    +
    + + + + diff --git a/docs/modules/overrides.table.html b/docs/modules/overrides.table.html new file mode 100644 index 00000000..20f2ea68 --- /dev/null +++ b/docs/modules/overrides.table.html @@ -0,0 +1,2015 @@ + + + + + + + + overrides.table module + + + + + + + +
    +
    + + + + + + + +
    + + + + + + + + +

    overrides.table module

    +

    Searches a table to remove a specific element without an index

    +

    + + + + + + + + + + + + + +

    Dependencies

    + + + + + + + +
    overrides.inspect
    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    remove_index(tbl, index)Removes an item from an array in O(1) time.
    merge_table(t1, t2)Adds the contents of table t2 to table t1
    array_insert(tbl[, start_index], values)Much faster method for inserting items into an array
    table_insert(tbl[, start_index], tbl2)Much faster method for inserting keys into a table
    get_key(t, e)Checks if a table contains an element
    get_index(t, e)Checks if the arrayed portion of a table contains an element
    contains(t, e)Checks if a table contains an element
    array_contains(t, e)Checks if the arrayed portion of a table contains an element
    extract_keys(tbl, ...)Extracts certain keys from a table
    set(t, index, element)Adds an element into a specific index position while shuffling the rest down
    get_random_dictionary_entry(t, key)Chooses a random entry from a table + because this uses math.random, it cannot be used outside of events
    get_random_weighted(weighted_table, item_index, weight_index)Chooses a random entry from a weighted table + because this uses math.random, it cannot be used outside of events
    clear_table(t, array)Clears all existing entries in a table
    shuffle_table(t, rng)Creates a fisher-yates shuffle of a sequential number-indexed table + because this uses math.random, it cannot be used outside of events if no rng is supplied + from: http://www.sdknews.com/cross-platform/corona/tutorial-how-to-shuffle-table-items
    get_values(tbl[, sorted][, as_string])Returns a copy of all of the values in the table.
    get_keys(tbl[, sorted][, as_string])Returns a copy of all of the keys in the table.
    alphanumsort(tbl)Returns the list is a sorted way that would be expected by people (this is by key)
    keysort(tbl)Returns the list is a sorted way that would be expected by people (this is by key) (faster alternative than above)
    + + +

    Fields

    + + + + + + + + + + + + + + + + + + + + + + + + +
    inspectSimilar to serpent.block, returns a string with a pretty representation of a table.
    sizeTakes a table and returns the number of entries in the table.
    deep_copyCreates a deepcopy of a table.
    mergeMerges multiple tables.
    equalsDetermines if two tables are structurally equal.
    + + +
    + + +

    Dependencies

    +
    +
    +
    +
    + # + overrides.inspect +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +

    Functions

    +
    +
    +
    +
    + # + remove_index(tbl, index) +
    +
    +
    +
    + +

    Removes an item from an array in O(1) time.

    +

    + The catch is that fast_remove doesn't guarantee to maintain the order of items in the array.

    + + + Parameters: + +
      + + + + + +
    • + + tbl + + : + + + arrayed table + + + + + + + +
    • + + index + + : + + + Must be >= 0. The case where index > #tbl is handled. + +
    • + + + + + + + + + + + + + + + + + +
      +
      +
      + # + merge_table(t1, t2) +
      +
      +
      +
      + +

      Adds the contents of table t2 to table t1

      +

      + + + Parameters: + +
        + + + + + +
      • + + t1 + + : + + +
      to insert into + + + + + + + +
    • + + t2 + + : + + +
    • to insert from + + + + + + + + + + + + + + + + + + + +
      +
      +
      + # + array_insert(tbl[, start_index], values) +
      +
      +
      +
      + +

      Much faster method for inserting items into an array

      +

      + + + Parameters: + +
        + + + + + +
      • + + tbl + + : + + (table) + + the table that will have the values added to it + +
      • + + + + + +
      • + + start_index + + : + + (number) + + the index at which values will be added, nil means end of the array + + (optional) +
      • + + + + + +
      • + + values + + : + + (table) + + the new values that will be added to the table + +
      • + + +
      + + + + + Returns: +
        +
      • + (table) + the table that was passed as the first argument +
      • +
      + + + + + + + + Usage: +
      -- Adding 1000 values into the middle of the array
      +local tbl = {}
      +local values = {}
      +for i = 1,1000 do tbl[i] = i values[i] = i end
      +table.array_insert(tbl,500,values) -- around 0.4ms
      + + +
      +
      +
      +
      + # + table_insert(tbl[, start_index], tbl2) +
      +
      +
      +
      + +

      Much faster method for inserting keys into a table

      +

      + + + Parameters: + +
        + + + + + +
      • + + tbl + + : + + (table) + + the table that will have keys added to it + +
      • + + + + + +
      • + + start_index + + : + + (number) + + the index at which values will be added, nil means end of the array, numbered indexs only + + (optional) +
      • + + + + + +
      • + + tbl2 + + : + + (table) + + the table that may contain both string and numbered keys + +
      • + + +
      + + + + + Returns: +
        +
      • + (table) + the table passed as the first argument +
      • +
      + + + + + + + + Usage: +
      -- Merging two tables
      +local tbl = {}
      +local tbl2 = {}
      +for i = 1,100 do tbl[i] = i tbl['_'..i] = i tbl2[i] = i tbl2['__'..i] = i end
      +table.table_insert(tbl,50,tbl2)
      + + +
      +
      +
      +
      + # + get_key(t, e) +
      +
      +
      +
      + +

      Checks if a table contains an element

      +

      + + + Parameters: + +
        + + + + + +
      • + + t + + : + + +
      + + + + + + + +
    • + + e + + : + + + table element + +
    • + + + + + + + + Returns: +
        +
      • + the index of the element or nil +
      • +
      + + + + + + + + + + +
      +
      +
      + # + get_index(t, e) +
      +
      +
      +
      + +

      Checks if the arrayed portion of a table contains an element

      +

      + + + Parameters: + +
        + + + + + +
      • + + t + + : + + +
      + + + + + + + +
    • + + e + + : + + + table element + +
    • + + + + + + + + Returns: +
        +
      • + the index of the element or nil +
      • +
      + + + + + + + + + + +
      +
      +
      + # + contains(t, e) +
      +
      +
      +
      + +

      Checks if a table contains an element

      +

      + + + Parameters: + +
        + + + + + +
      • + + t + + : + + +
      + + + + + + + +
    • + + e + + : + + + table element + +
    • + + + + + + + + Returns: +
        +
      • + indicating success +
      • +
      + + + + + + + + + + +
      +
      +
      + # + array_contains(t, e) +
      +
      +
      +
      + +

      Checks if the arrayed portion of a table contains an element

      +

      + + + Parameters: + +
        + + + + + +
      • + + t + + : + + +
      + + + + + + + +
    • + + e + + : + + + table element + +
    • + + + + + + + + Returns: +
        +
      • + indicating success +
      • +
      + + + + + + + + + + +
      +
      +
      + # + extract_keys(tbl, ...) +
      +
      +
      +
      + +

      Extracts certain keys from a table

      +

      + + + Parameters: + +
        + + + + + +
      • + + tbl + + : + + (table) + + table the which contains the keys + +
      • + + + + + +
      • + + ... + + : + + (string) + + the names of the keys you want extracted + +
      • + + +
      + + + + + Returns: +
        +
      • + the keys in the order given +
      • +
      + + + + + + + + Usage: +
      local key_three, key_one = extract({key_one='foo',key_two='bar',key_three=true},'key_three','key_one')
      + + +
      +
      +
      +
      + # + set(t, index, element) +
      +
      +
      +
      + +

      Adds an element into a specific index position while shuffling the rest down

      +

      + + + Parameters: + +
        + + + + + +
      • + + t + + : + + +
      to add into + + + + + + + +
    • + + index + + : + + + the position in the table to add to + +
    • + + + + + +
    • + + element + + : + + + to add to the table + +
    • + + + + + + + + + + + + + + + + + +
      +
      +
      + # + get_random_dictionary_entry(t, key) +
      +
      +
      +
      + +

      Chooses a random entry from a table + because this uses math.random, it cannot be used outside of events

      +

      + + + Parameters: + +
        + + + + + +
      • + + t + + : + + +
      + + + + + + + +
    • + + key + + : + + + to indicate whether to return the key or value + +
    • + + + + + + + + Returns: +
        +
      • + a random element of table t +
      • +
      + + + + + + + + + + +
      +
      +
      + # + get_random_weighted(weighted_table, item_index, weight_index) +
      +
      +
      +
      + +

      Chooses a random entry from a weighted table + because this uses math.random, it cannot be used outside of events

      +

      + + + Parameters: + +
        + + + + + +
      • + + weighted_table + + : + + +
      of tables with items and their weights + + + + + + + +
    • + + item_index + + : + + + of the index of items, defaults to 1 + +
    • + + + + + +
    • + + weight_index + + : + + + of the index of the weights, defaults to 2 + +
    • + + + + + + + + Returns: +
        +
      • + table element +
      • +
      + + + + + + + + + + +
      +
      +
      + # + clear_table(t, array) +
      +
      +
      +
      + +

      Clears all existing entries in a table

      +

      + + + Parameters: + +
        + + + + + +
      • + + t + + : + + +
      to clear + + + + + + + +
    • + + array + + : + + + to indicate whether the table is an array or not + +
    • + + + + + + + + + + + + + + + + + +
      +
      +
      + # + shuffle_table(t, rng) +
      +
      +
      +
      + +

      Creates a fisher-yates shuffle of a sequential number-indexed table + because this uses math.random, it cannot be used outside of events if no rng is supplied + from: http://www.sdknews.com/cross-platform/corona/tutorial-how-to-shuffle-table-items

      +

      + + + Parameters: + +
        + + + + + +
      • + + t + + : + + +
      to shuffle + + + + + + + +
    • + + rng + + : + + + to provide random numbers + +
    • + + + + + + + + + + + + + + + + + +
      +
      +
      + # + get_values(tbl[, sorted][, as_string]) +
      +
      +
      +
      + +

      Returns a copy of all of the values in the table.

      +

      + + + Parameters: + +
        + + + + + +
      • + + tbl + + : + + (table) + + the 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 +
      • +
      + + + + + + + + + +
      +
      +
      +
      + # + get_keys(tbl[, sorted][, as_string]) +
      +
      +
      +
      + +

      Returns a copy of all of the keys in the table.

      +

      + + + Parameters: + +
        + + + + + +
      • + + tbl + + : + + (table) + + the 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 +
      • +
      + + + + + + + + + +
      +
      +
      +
      + # + 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 +
      • +
      + + + + + + + + + +
      +
      +
      +
      + # + keysort(tbl) +
      +
      +
      +
      + +

      Returns the list is a sorted way that would be expected by people (this is by key) (faster alternative than above)

      +

      + + + Parameters: + +
        + + + + + +
      • + + tbl + + : + + (table) + + the table to be sorted + +
      • + + +
      + + + + + Returns: +
        +
      • + (table) + the sorted table +
      • +
      + + + + + + + + + +
      + +

      Fields

      +
      +
      +
      +
      + # + inspect +
      +
      +
      +
      + +

      Similar to serpent.block, returns a string with a pretty representation of a table.

      +

      + Notice: This method is not appropriate for saving/restoring tables. It is meant to be used by the programmer mainly while debugging a program. + depth sets the maximum depth that will be printed out. When the max depth is reached, inspect will stop parsing tables and just return {...} + process is a function which allow altering the passed object before transforming it into a string. + A typical way to use it would be to remove certain values so that they don't appear at all. + return the prettied table

      + + + +
        + + + + + +
      • + + table + + : + + +
      the table to serialize + + + + + + + +
    • + + options + + : + + +
    • options are depth, newline, indent, process + + + + + + + + + + + + + + + + + + + +
      +
      +
      + # + size +
      +
      +
      +
      + +

      Takes a table and returns the number of entries in the table.

      +

      (Slower than #table, faster than iterating via pairs)

      + + + + + + + + + + + + + + +
      +
      +
      +
      + # + deep_copy +
      +
      +
      +
      + +

      Creates a deepcopy of a table.

      +

      Metatables and LuaObjects inside the table are shallow copies. + Shallow copies meaning it copies the reference to the object instead of the object itself.

      + + + +
        + + + + + +
      • + + object + + : + + +
      the object to copy + + + + + + + + + + + + + + + + + + + +
      +
      +
      + # + merge +
      +
      +
      +
      + +

      Merges multiple tables.

      +

      Tables later in the list will overwrite entries from tables earlier in the list. + Ex. merge({{1, 2, 3}, {[2] = 0}, {[3] = 0}}) will return {1, 0, 0}

      + + + +
        + + + + + +
      • + + tables + + : + + +
      takes a table of tables to merge + + + + + + + + + + + + + + + + + + + +
      +
      +
      + # + equals +
      +
      +
      +
      + +

      Determines if two tables are structurally equal.

      +

      + Notice: tables that are LuaObjects or contain LuaObjects won't be compared correctly, use == operator for LuaObjects

      + + + +
        + + + + + +
      • + + tbl1 + + : + + +
      + + + + + + + +
    • + + tbl2 + + : + + +
    • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index 0613535f..beaa2b20 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -29,7 +29,7 @@

      ExpGaming Scenario

      -

      Explosive Gaming's server scenario for 0.17

      +

      Explosive Gaming's server scenario for 0.18

      @@ -51,18 +51,13 @@

      Modules

      @@ -70,13 +65,13 @@ @@ -105,10 +100,12 @@ + + @@ -117,8 +114,10 @@

      Guis

      @@ -156,7 +155,6 @@

      Configs

      @@ -343,7 +342,7 @@ - +
      utils.token
      utils.debugoverrides.debug
      @@ -488,8 +487,8 @@
      - # - utils.debug + # + overrides.debug
      @@ -1292,7 +1291,7 @@ generated by LDoc
    diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index 4714e6ed..c270c6ce 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,18 +50,13 @@

    Modules

    @@ -69,13 +64,13 @@ @@ -104,10 +99,12 @@ + + @@ -116,8 +113,10 @@

    Guis

    @@ -155,7 +154,6 @@

    Configs

    @@ -434,7 +433,7 @@ generated by LDoc
    diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index 4d025c24..43b62a10 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -51,18 +51,13 @@

    Modules

    @@ -70,13 +65,13 @@ @@ -105,10 +100,12 @@ + + @@ -117,8 +114,10 @@

    Guis

    @@ -156,7 +155,6 @@

    Configs

    @@ -651,7 +650,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index 6d78546c..293edf6c 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,13 +50,13 @@ @@ -85,10 +85,12 @@ + + @@ -97,8 +99,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -789,7 +788,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index 488a3235..d9e08d04 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -29,7 +29,7 @@

    ExpGaming Scenario

    -

    Explosive Gaming's server scenario for 0.17

    +

    Explosive Gaming's server scenario for 0.18

    @@ -50,13 +50,13 @@ @@ -85,10 +85,12 @@ + + @@ -97,8 +99,10 @@

    Guis

    @@ -136,7 +140,6 @@

    Configs

    @@ -169,18 +173,13 @@

    Modules

    @@ -240,7 +239,7 @@

    6) The scenario will now load all the selected modules and start the map, any errors or exceptions raised in the scenario should not cause a game/server crash, so if any features do not work as expected then it may be returning an error in the log. Please report these errors to [the issues page](issues).

    ## Contributing -

    All are welcome to make pull requests and issues for this scenario, if you are in any doubt, please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. All our docs can be found [here][docs]. Please keep in mind while making code changes: +

    All are welcome to make pull requests and issues for this scenario, if you are in any doubt, please ask someone in our [discord]. If you do not know lua and don't feel like learning you can always make a [feature request]. To find out what we already have please read our [docs]. Please keep in mind while making code changes:

    * New features should have the branch names: `feature/feature-name` * New features are merged into `dev` after it has been completed, this can be done through a pull request. * After a number of features have been added a release branch is made: `release/X.Y.0` @@ -338,7 +337,7 @@ Please report these errors to [the issues page](issues). generated by LDoc

    diff --git a/expcore/async.lua b/expcore/async.lua index a988563b..473580ae 100644 --- a/expcore/async.lua +++ b/expcore/async.lua @@ -1,31 +1,31 @@ --[[-- Core Module - Async - - An extention of task and token to allow a single require to register and run async functions. - @core Async - @alias Async +- An extention of task and token to allow a single require to register and run async functions. +@core Async +@alias Async - @usage - -- To use Async you must register the allowed functions when the files are loaded, often this will just be giving access to - -- some functions within a module if you expect that some parts may be blocked by in game permissions or a custom system you have made - -- you may also want to register functions that you want to have a delayed call, such as waiting 2 seconds before printing a message +@usage +-- To use Async you must register the allowed functions when the file is loaded, often this will just be giving access to +-- some functions within a module if you expect that at part may be blocked by in game permissions or a custom system you have made +-- you may also want to register functions that you want to have a time delay, such as waiting 2 seconds before printing a message - -- This player.admin is called (command or gui element event) by a player who isnt admin then it will error - -- here we register the function to promote the player so that it will run async - local promote_player = - Async.register(function(player) - player.admin = true - end) +-- When player.admin is called (either command or gui element event) by a player who isnt admin then it will error +-- here we register the function to promote the player so that it will run async and outside the player scope +local promote_player = +Async.register(function(player) + player.admin = true +end) - -- This will allow us to bypass this by running one tick later outside of any player scope - Async(promote_player,game.player) +-- This will allow us to bypass the error by running one tick later outside of any player scope +Async(promote_player,game.player) - -- Here we make an sync function that we want to have a delay, note the delay is not defined here - local print_message = - Async.register(function(player,message) - player.print(message) - end) +-- Here we make an sync function that we want to have a delay, note the delay is not defined here +local print_message = +Async.register(function(player,message) + player.print(message) +end) - -- We can then call the async function with a delay using the wait function - Async.wait(60,print_message,game.player,'One second has passed!') +-- We can then call the async function with a delay using the wait function +Async.wait(60, print_message, game.player, 'One second has passed!') ]] local Task = require 'utils.task' --- @dep utils.task @@ -39,13 +39,38 @@ Token.register(function(params) return func(unpack(params.params)) end) ---- Register a new async function, must called when the file is loaded --- @tparam function callback the function that will become an async function +--[[-- Register a new async function, must called when the file is loaded +@function register +@tparam function callback the function that can be called as an async function +@treturn string the uid of the async function which can be passed to Async.run and Async.wait + +@usage-- Registering a function to set the admin state of a player +local set_admin = +Async.register(function(player, state) + if player.valid then + player.admin = state + end +end) + +@usage-- Registering a function to print to a player +local print_to_player = +Async.register(function(player, message) + if player.valid then + player.print(message) + end +end) + +]] Async.register = Token.register ---- Runs the async function linked to this token, you may supply any number of params as needed --- @tparam string token the token of the async function you want to run --- @tparam[opt] any ... the other params that you want to pass to your function +--[[-- Runs an async function, you may supply any number of arguments as required by that function +@tparam string token the token of the async function you want to run +@tparam[opt] any ... the other params that you want to pass to your function + +@usage-- Make a player admin regardless of if you are admin +Async.run(set_admin, player, true) + +]] function Async.run(token,...) Task.queue_task(internal_run, { token = token, @@ -53,10 +78,15 @@ function Async.run(token,...) }) end ---- Runs the async function linked to this token after the given number of ticks, you may supply any number of params as needed --- @tparam number ticks the number of ticks that you want the function to run after --- @tparam string token the token of the async function you want to run --- @tparam[opt] any ... the other params that you want to pass to your function +--[[-- Runs an async function after the given number of ticks, you may supply any number of arguments as required by that function +@tparam number ticks the number of ticks that you want the function to run after +@tparam string token the token of the async function you want to run +@tparam[opt] any ... the other params that you want to pass to your function + +@usage-- Print a message to a player after 5 seconds +Async.wait(300, print_to_player, 'Hello, World!') + +]] function Async.wait(ticks,token,...) Task.set_timeout_in_ticks(ticks, internal_run, { token = token, diff --git a/expcore/commands.lua b/expcore/commands.lua index b84adea4..a249ee93 100644 --- a/expcore/commands.lua +++ b/expcore/commands.lua @@ -1,197 +1,193 @@ --[[-- Core Module - Commands - - Factorio command making module that makes commands with better parse and more modularity - @core Commands - @alias Commands +- Factorio command making module that makes commands with better parse and more modularity +@core Commands +@alias Commands - @usage ----- Example Authenticator: - -- The command system is most useful when you can control who can use commands; to do this would would need to - -- define an authenticator which is ran every time a command is run; in this example I will show a simple one - -- that requires some commands to require the user to be a game admin: +@usage--- Full code example, see below for explaination +Commands.new_command('repeat-name', 'Will repeat you name a number of times in chat.') +:add_param('repeat-count', false, 'number-range-int', 1, 5) -- required int in range 1 to 5 inclusive +:add_param('smiley', true, function(input, player, reject) -- optional boolean default false + if not input then return end + if input:lower() == 'true' or input:lower() == 'yes' then + return true + else + return false + end +end) +:set_defaults{ smiley=false } +:set_flag('admin_only', true) -- command is admin only +:add_alias('name', 'rname') -- allow alias: name and rname +:register(function(player, repeat_count, smiley, raw) + game.print(player.name..' used a command with input: '..raw) - -- When the authenticator is called be the command handler it will be passed 4 vales: - -- 1) the player who used the command - -- 2) the name of the command that is being used - -- 3) any flags which have been set for this command, this is a table of values set using :set_flag(name,value) - -- 4) the reject function which is the preferred method to prevent execution of the command + local msg = ') '..player.name + if smiley then + msg = ':'..msg + end - -- For our admin only example we will set a flag to true when we want it do be admin only so when we define the - -- command will will use :set_flag('admin_only',true) and then inside the authenticator we will test if the flag - -- is present using: if flags.admin_only then + for 1 = 1,repeat_count do + Command.print(1..msg) + end +end) - -- Although no return is required to allow the command to execute it is best practice to return true; we do this in - -- two cases in our authenticator: - -- 1) when the "admin_only" flag is not set, which we take to mean any one can use it - -- 2) when the "admin_only" flag is set, and the player is admin +@usage--- Example Command: +-- How for the fun part making the commands, the commands can be set up with any number of params and flags that you want, +-- you can add aliases for the commands and set default values for optional params and of course register your command callback +-- in our example we will just have a command that will repeat the users name in chat X amount of times and only allow admins to use it. - -- Now when the user is not an admin and the command requires you to be an admin then we must reject the request: - -- 1) return false -- this is the most basic block and should only be used while testing - -- 2) return reject -- returning the reject function is only an option as a fail safe, same as returning false - -- 3) reject() -- this will block execution without returning to allow further code to be ran in the authenticator - -- 4) reject('This command is for admins only!') -- Using reject as a function allows a error message to be returned - -- 5) return reject() -- using return on either case above is best practice as you should execute all code before rejecting +-- First we create the new command, nb this will not register the command to the game this is done at the end, we will call +-- the command "repeat-name" and set the help message as follows: +Commands.new_command('repeat-name', 'Will repeat you name a number of times in chat.') - -- Example Code: - Commands.add_authenticator(function(player,command,flags,reject) - if flags.admin_only then -- our test for the "admin_only" flag - if player.admin then - return true -- true return 2 - else - return reject('This command is for admins only!') -- reject return 5 with a custom error message - end - else - return true -- true return 1 - end - end) +-- Now for our first param we will call "repeat-count" and it will be a required value between 1 and 5 inclusive: +:add_param('repeat-count', false, 'number-range-int', 1, 5) - @usage ----- Example Parse: - -- Before you go making commands it is important to understand the most powerful feature of this command handler, - -- when you define a command you are able to type the params and have then be parsed by an handler so before your - -- command is ever executed you can be sure that all the params are valid. This module should be paired with a general - -- command parse but you may want to create your own: +-- Our second param we need a custom parse for but we have not defined it, this is an option for when it is unlikely for +-- any other command to use the same input type; however in our case it will just be a boolean which should be noted as being +-- included in the general command parse config. As for the param its self it will be called "smiley" and will be optional with +-- a default value of false: +:add_param('smiley', true, function(input, player, reject) + -- since it is optional the input can be nil, in which case we just return + if not input then return end + -- if it is not nil then we check for a truthy value + if input:lower() == 'true' or input:lower() == 'yes' then + return true + else + -- note that because we did not return nil or reject then false will be passed to command callback, see example parse + return false + end +end) - -- For our example we will create a parse to accept only integer numbers in a given range: - -- 1) we will give it the name "number-range-int" this is the "type" that the input is expected to be - -- 2) when we define the type we will also define the min and max of the range so we can use the function more than once - -- Example parse usage: - :add_param('repeat_count',false,'number-range-int',5,10) -- range 5 to 10 inclusive +-- Once all params are defined you can now define some default values if you have optional params, the default value will be used only +-- when no value is given as input, if an invalid value is given then the command will still fail and this value will not be used, the +-- default can also be a function which is passed the player using the command and returns a value. Here we set the default for "smiley" to false: +:set_defaults{smiley=false} - -- The command parse will be passed 3 params and any other you define, in our case: - -- 1) the input that has been given by the user for this param, the role of this function is to transform this value - -- nb: the input is a string but can be nil if the param is marked as optional - -- 2) the player who is using the command, this is always present - -- 3) the reject function to throw an error to the user, this is always present - -- 4) the range min, this is user defined and has the value given when the param is defined - -- 5) the range max, this is user defined and has the value given when the param is defined +-- Another example of defaults if we have: item, amount[opt], player[opt] +:set_defaults{ + amount = 50, -- more than one value can be set at a time + player = function(player) + return player -- default is the player using the command + end +} - -- When returning from the param parse you again have a few options with how to do this: - -- 1) you return the new value for the param (any non nil value) this value is then passed to the command callback - -- 2) not returning will cause a generic invalid error and the command callback is blocked, not recommenced - -- 3) return reject -- this is just a failsafe in case the function is not called, same as no return - -- 4) return reject() -- will give a shorter error message as you pass a nil custom error - -- 5) return reject('Number entered is not in range: '..range_min..', '..range_max) -- returns a custom error the the user - -- nb: if you do not return reject after you call it then you are still returning nil so there will be a duplicate message +-- Now the params are set up we can alter how the command works, we can set auth flags, add aliases to this command or enable "auto concat" +-- which is when you want all extra words to be concatenated onto the end of the last param, useful for reason or messages: +:set_flag('admin_only', true) -- in our case we want "admin_only" to be set to true so only admins can use the command +:add_alias('name', 'rname') -- we also add two aliases here: "name" and "rname" which point to this command +-- :enable_auto_concat() we do not use this in our case but this can also be used to enable the "auto concat" feature - -- It should be noted that if you want to expand on an existing parse you can use Commands.parse(type,input,player,reject) - -- and this value will either return a new value for the input or nil, if it is nil you should return nil to prevent double - -- messages to the user: - input = Commands.parse('number-int',input,player,reject) - if not input then return end -- nil check +-- And finally we want to register a callback to this command, the callback is what defines what the command does, can be as complex as you +-- want it to be to as simple as our example; the command receives two params plus all that you have defines: +-- 1) the player who used the command +-- 2) in our case repeat_count which will be a number +-- 3) in our case smiley which will be a boolean +-- 4) the raw input; this param is always last as is always present as a catch all +:register(function(player, repeat_count, smiley, raw) + -- this is to show the value for raw as this is an example command, the log file will also show this + game.print(player.name..' used a command with input: '..raw) + local msg = ') '..player.name + if smiley then + -- this is where that smiley param is used + msg = ':'..msg + end + for 1 = 1,repeat_count do + -- this print function will return ANY value to the user in a desync safe manor, this includes if the command was used through rcon + Command.print(1..msg) + end + -- see below for what else can be used here +end) - -- Example Code: - Commands.add_parse('number-range-int',function(input,player,reject,range_min,range_max) - local rtn = tonumber(input) and math.floor(tonumber(input)) or nil -- converts input to number - if not rtn or rtn < range_min or rtn > range_max then - -- the input is either not a number or is outside the range - return reject('Number entered is not in range: '..range_min..', '..range_max) - else - -- returns the input as a number value rather than a string, thus the param is now the correct type - return rtn - end - end) +-- Other values that can be returned from register +Commands.print(any,colour[opt]) -- this will return any value value to the user including if it is ran through rcon console +Commands.error(message[opt]) -- this returns a warning to the user, aka an error that does not prevent execution of the command +return Commands.error(message[opt]) -- this returns an error to the user, and will halt the command execution, ie no success message is returned +Commands.success(message[opt]) -- used to return a success message however don't use this method see below +return Commands.success(message[opt]) -- will return the success message to the user and your given message, halts execution +return -- if any value is returned then it will be returned to the player via a Commands.success call - @usage ----- Example Command: - -- How for the fun part making the commands, the commands can be set up with any number of params and flags that you want, - -- you can add aliases for the commands and set default values for optional params and of course register your command callback - -- in our example we will just have a command that will repeat the users name in chat X amount of times and only allow admins to use it. +@usage--- Example Authenticator: +-- The command system is best used when you can control who uses commands; +-- to do this would would need to define an authenticator which is ran every time a command is run; +-- in this example I will show a simple one that requires certain commands to require the user to be a game admin. - -- First we create the new command, nb this will not register the command to the game this is done at the end, we will call - -- the command "repeat-name" and set the help message as follows: - Commands.new_command('repeat-name','Will repeat you name a number of times in chat.') +-- For our admin only example we will set a flag to true when we want it to be admin only; +-- when we define the command will will use :set_flag('admin_only', true); +-- then inside the authenticator we will test if the flag is present using: if flags.admin_only then - -- Now for our first param we will call "repeat-count" and it will be a required value between 1 and 5 inclusive: - :add_param('repeat-count',false,'number-range-int',1,5) +-- When the authenticator is called by the command handler it will be passed 4 arguments: +-- 1) player - the player who used the command +-- 2) command - the name of the command that is being used +-- 3) flags - the flags which have been set for this command, flags are set with :set_flag(name, value) +-- 4) reject - the reject function which is the preferred method to prevent execution of the command - -- Our second param we need a custom parse for but we have not defined it, this is an option for when it is unlikely for - -- any other command to use the same input type; however in our case it will just be a boolean which should be noted as being - -- included in the general command parse config. As for the param its self it will be called "smiley" and will be optional with - -- a default value of false: - :add_param('smiley',true,function(input,player,reject) - -- since it is optional the input can be nil, in which case we just return - if not input then return end - -- if it is not nil then we check for a truthy value - if input:lower() == 'true' or input:lower() == 'yes' then - return true - else - -- note that because we did not return nil or reject then false will be passed to command callback, see example parse - return false - end - end) +-- No return is required to allow the command to execute but it is best practice to return true; +-- we do this in two cases in our authenticator: +-- 1) when the "admin_only" flag is not set, which we take assume that any one can use it +-- 2) when the "admin_only" flag is set, and the player is admin - -- Once all params are defined you can now define some default values if you have optional params, the default value will be used only - -- when no value is given as input, if an invalid value is given then the command will still fail and this value will not be used, the - -- default can also be a function which is passed the player using the command and returns a value. Here we set the default for "smiley" to false: - :set_defaults{smiley=false} +-- When want to prevent exicution of the command we must reject it, listed is how that can be done: +-- 1) return false -- this is the most basic rejection and should only be used while testing +-- 2) return reject -- returning the reject function is as a fail safe in case you forget to call it, same as returning false +-- 3) reject() -- this will block execution without to allowing further code to be ran in your authenticator +-- 4) reject('This command is for admins only!') -- Using reject as a function allows a error message to be returned +-- 5) return reject() -- using return on either case above is best practice as you should execute all your code before rejecting - -- Another example of defaults if we have: item, amount[opt], player[opt] - :set_defaults{ - amount = 50, -- more than one value can be set at a time - player = function(player) - return player -- default is the player using the command - end - } +-- Example Code: +Commands.add_authenticator(function(player, command, flags, reject) + -- Check if the command is admin only + if flags.admin_only then + -- Return true if player is admin, or reject and return error message + return player.admin or reject('This command is for admins only!') + else + -- Return true if command was not admin only + return true + end +end) - -- Now the params are set up we can alter how the command works, we can set auth flags, add aliases to this command or enable "auto concat" - -- which is when you want all extra words to be concatenated onto the end of the last param, useful for reason or messages: - :set_flag('admin_only',true) -- in our case we want "admin_only" to be set to true so only admins can use the command - :add_alias('name','rname') -- we also add two aliases here: "name" and "rname" which point to this command - -- :enable_auto_concat() we do not use this in our case but this can also be used to enable the "auto concat" feature +@usage--- Example Parse: +-- Before you make a command it is important to understand the most powerful feature of this command handler; +-- when you define a command you are able to type the params and have then be parsed and validated before your command is executed; +-- This module should is paired with a general command parse but you may want to create your own. - -- And finally we want to register a callback to this command, the callback is what defines what the command does, can be as complex as you - -- want it to be to as simple as our example; the command receives two params plus all that you have defines: - -- 1) the player who used the command - -- 2) in our case repeat_count which will be a number - -- 3) in our case smiley which will be a boolean - -- 4) the raw input; this param is always last as is always present as a catch all - :register(function(player,repeat_count,smiley,raw) - -- this is to show the value for raw as this is an example command, the log file will also show this - game.print(player.name..' used a command with input: '..raw) - local msg = ') '..player.name - if smiley then - -- this is where that smiley param is used - msg = ':'..msg - end - for 1 = 1,repeat_count do - -- this print function will return ANY value to the user in a desync safe manor, this includes if the command was used through rcon - Command.print(1..msg) - end - -- see below for what else can be used here - end) +-- For our example we will create a parse to accept only integer numbers in a given range: +-- 1) we will give it the name "number-range-int" this is the "type" that the input is expected to be +-- 2) when we define the type we will also define the min and max of the range so we can use the function more than once +:add_param('repeat_count', false, 'number-range-int', 5, 10) -- "repeat_count" is required "number-range-int" in a range 5 to 10 inclusive - -- Some other useful functions that can be used are: - Commands.print(any,colour[opt]) -- this will return any value value to the user including if it is ran through rcon console - Commands.error(message[opt]) -- this returns a warning to the user, aka an error that does not prevent execution of the command - return Commands.error(message[opt]) -- this returns an error to the user, and will halt the command execution, ie no success message is returned - Commands.success(message[opt]) -- used to return a success message however don't use this method see below - return Commands.success(message[opt]) -- will return the success message to the user and your given message, halts execution - return if any value is returned then it will be returned to the player via a Commands.success call +-- The command parse will be passed 3 arguments plus any other which you define, in our case: +-- 1) input - the input that has been given by the user for this param, the role of this function is to transform this value +-- nb: the input is a string but can be nil if the param is marked as optional +-- 2) player - the player who is using the command, this is always present +-- 3) reject - the reject function to throw an error to the user, this is always present +-- 4) range_min - the range min, this is user defined and has the value given when the param is defined +-- 5) range_max - the range max, this is user defined and has the value given when the param is defined - -- Example Code: - Commands.new_command('repeat-name','Will repeat you name a number of times in chat.') - :add_param('repeat-count',false,'number-range-int',1,5) -- required int in range 1 to 5 inclusive - :add_param('smiley',true,function(input,player,reject) -- optional boolean default false - if not input then return end - if input:lower() == 'true' or input:lower() == 'yes' then - return true - else - return false - end - end) - :set_defaults{smiley=false} - :set_flag('admin_only',true) -- command is admin only - :add_alias('name','rname') -- allow alias: name and rname - :register(function(player,repeat_count,smiley,raw) - game.print(player.name..' used a command with input: '..raw) - local msg = ') '..player.name - if smiley then - msg = ':'..msg - end - for 1 = 1,repeat_count do - Command.print(1..msg) - end - end) +-- When returning from the param parse you have a few options with how to do this: +-- 1) you return the new value for the param (any non nil value) this value is then passed to the command callback +-- 2) not returning will cause a generic invalid error and the command is rejected, not recommenced +-- 3) return reject -- this is just a failsafe in case the function is not called, same as no return +-- 4) return reject() -- will give a shorter error message as you pass a nil custom error +-- 5) return reject('Number entered is not in range: '..range_min..', '..range_max) -- returns a custom error to the user +-- nb: if you do not return reject after you call it then you will still be returning nil so there will be a duplicate error message + +-- It should be noted that if you want to expand on an existing parse you can use Commands.parse(type, input, player, reject) +-- this function will either return a new value for the input or nil, if it is nil you should return nil to prevent duplicate +-- error messages to the user: +input = Commands.parse('number-int', input, player, reject) +if not input then return end -- nil check + +-- Example Code: +Commands.add_parse('number-range-int',function(input, player, reject, range_min, range_max) + local rtn = tonumber(input) and math.floor(tonumber(input)) or nil -- converts input to number + if not rtn or rtn < range_min or rtn > range_max then + -- the input is either not a number or is outside the range + return reject('Number entered is not in range: '..range_min..', '..range_max) + else + -- returns the input as a number value rather than a string, thus the param is now the correct type + return rtn + end +end) ]] @@ -199,38 +195,58 @@ local Game = require 'utils.game' --- @dep utils.game local player_return,write_json = _C.player_return, _C.write_json --- @dep expcore.common local Commands = { - defines={ -- common values are stored error like signals + --- Values returned by the signal functions to cause the command system to react + defines = { error='CommandError', unauthorized='CommandErrorUnauthorized', success='CommandSuccess' }, - commands={}, -- custom command data will be stored here - authorization_fail_on_error=false, -- set true to have authorize fail if a callback fails to run, more secure - authorization={}, -- custom function are stored here which control who can use what commands - parse_functions={}, -- used to store default functions which are common parse function such as player or number in range - print=player_return, -- short cut so player_return does not need to be required in every module - _prototype={}, -- used to store functions which gets added to new custom commands + --- Custom command data will be stored here + commands={}, + --- Set true to have authorize fail if a callback fails to run, more secure + authorization_fail_on_error=false, + --- Custom function are stored here which control who can use what commands + authorization={}, + --- Used to store default functions which are common parse function such as player or number in range + parse_functions={}, + -- Sends a value to the player, different to success as this does not signal the end of your command + print=player_return, + --- Used to store functions which gets added to new custom commands + _prototype={}, } --- Authenication. -- Functions that control who can use commands -- @section auth ---- Adds an authorization callback, function used to check if a player if allowed to use a command --- @tparam function callback the callback you want to register as an authenticator --- callback param - player: LuaPlayer - the player who is trying to use the command --- callback param - command: string - the name of the command which is being used --- callback param - flags: table - any flags which have been set for the command --- callback param - reject: function(error_message?: string) - call to fail authorize with optional error message --- @treturn number the index it was inserted at use to remove the callback, if anon function used +--[[-- Adds an authorization callback, function used to check if a player if allowed to use a command +@tparam function callback the callback you want to register as an authenticator +@treturn number the index it was inserted at use to remove the callback, if anon function used + +@usage-- Test if a command is admin only and if the player is admin +local admin_authenticator = +Commands.add_authenticator(function(player, command, flags, reject) + if flags.admin_only then + return player.admin or reject('This command is for admins only!') + else + return true + end +end) + +]] function Commands.add_authenticator(callback) table.insert(Commands.authorization,callback) return #Commands.authorization end ---- Removes an authorization callback --- @tparam function|number callback the callback to remove, an index returned by add_authenticator can be passed --- @treturn boolean was the callback found and removed +--[[-- Removes an authorization callback +@tparam function|number callback the callback to remove, an index returned by add_authenticator can be passed +@treturn boolean if the callback found and removed successfuly + +@usage-- Removing the admin authenticator, can not be done dueing runtime +Commands.remove_authenticator(admin_authenticator) + +]] function Commands.remove_authenticator(callback) if type(callback) == 'number' then -- if a number is passed then it is assumed to be the index @@ -256,13 +272,18 @@ function Commands.remove_authenticator(callback) return false end ---- Mostly used internally, calls all authorization callbacks, returns if the player is authorized --- @tparam LuaPlayer player the player that is using the command, passed to callbacks --- @tparam string command_name the command that is being used, passed to callbacks --- @treturn[1] boolean true player is authorized --- @treturn[1] string commands const for success --- @treturn[2] boolean false player is unauthorized --- @treturn[2] string|locale_string the reason given by the authenticator +--[[-- Mostly used internally, calls all authorization callbacks, returns if the player is authorized +@tparam LuaPlayer player the player that is using the command, passed to callbacks +@tparam string command_name the command that is being used, passed to callbacks +@treturn[1] boolean true player is authorized +@treturn[1] string commands const for success +@treturn[2] boolean false player is unauthorized +@treturn[2] string|locale_string the reason given by the authenticator + +@usage-- Test if a player can use "repeat-name" +local authorized, status = Commands.authorize(game.player, 'repeat-name') + +]] function Commands.authorize(player,command_name) local failed if not player then return true end @@ -300,13 +321,22 @@ function Commands.authorize(player,command_name) return true, Commands.defines.success end end + --- Getters. -- Functions that get commands -- @section getters ---- Gets all commands that a player is allowed to use, game commands not included --- @tparam[opt] LuaPlayer player the player that you want to get commands of, nil will return all commands --- @treturn table all commands that that player is allowed to use, or all commands +--[[-- Gets all commands that a player is allowed to use, game commands are not included +@tparam[opt] LuaPlayer player the player that you want to get commands of, nil will return all commands +@treturn table all commands that that player is allowed to use, or all commands + +@usage-- Get the command you are allowed to use +local commands = Commands.get(game.player) + +@usage-- Get all commands that are registered +local commands = Commands.get() + +]] function Commands.get(player) player = Game.get_player_from_any(player) if not player then return Commands.commands end @@ -319,12 +349,20 @@ function Commands.get(player) return allowed end ---- Searches command names and help messages to find possible commands, game commands included --- @tparam string keyword the word which you are trying to find --- @tparam[opt] LuaPlayer allowed_player the player to get allowed commands of, if nil all commands are searched --- @treturn table all commands that contain the key word, and allowed by player if player given -function Commands.search(keyword,allowed_player) - local custom_commands = Commands.get(allowed_player) +--[[-- Searches command names and help messages to find possible commands, game commands are included +@tparam string keyword the word which you are trying to find in your search +@tparam[opt] LuaPlayer player the player to get allowed commands of, if nil all commands are searched +@treturn table all commands that contain the key word, and allowed by player if player given + +@usage-- Get all commands which "repeat" +local commands = Commands.search('repeat') + +@usage-- Get all commands which "repeat" and you are allowed to use +local commands = Commands.search('repeat', game.player) + +]] +function Commands.search(keyword,player) + local custom_commands = Commands.get(player) local matches = {} keyword = keyword:lower() -- loops over custom commands @@ -354,15 +392,25 @@ end -- Functions that help with parsing -- @section parse ---- Adds a parse function which can be called by name rather than callback (used in add_param) --- nb: this is not needed as you can use the callback directly this just allows it to be called by name --- @tparam string name the name of the parse, should be the type like player or player_alive, must be unique --- @tparam function callback the callback that is ran to parse the input --- parse param - input: string - the input given by the user for this param --- parse param - player: LuaPlayer - the player who is using the command --- parse param - reject: function(error_message) - use this function to send a error to the user and fail running --- parse return - the value that will be passed to the command callback, must not be nil and if reject then command is not run --- @treturn boolean was the parse added will be false if the name is already used +--[[-- Adds a parse function which can be called by name (used in add_param) +nb: this is not required as you can use the callback directly this just allows it to be called by name +@tparam string name the name of the parse, should be the type like player or player_alive, must be unique +@tparam function callback the callback that is ran to parse the input +@treturn boolean was the parse added will be false if the name is already used + +@usage-- Adding a parse to validate ints in a given range +Commands.add_parse('number-range-int', function(input, player, reject, range_min, range_max) + local rtn = tonumber(input) and math.floor(tonumber(input)) or nil -- converts input to number + if not rtn or rtn < range_min or rtn > range_max then + -- the input is either not a number or is outside the range + return reject('Number entered is not in range: '..range_min..', '..range_max) + else + -- returns the input as a number rather than a string, thus the param is now the correct type + return rtn + end +end) + +]] function Commands.add_parse(name,callback) if Commands.parse_functions[name] then return false @@ -372,18 +420,28 @@ function Commands.add_parse(name,callback) end end ---- Removes a parse function, see add_parse for adding them --- @tparam string name the name of the parse to remove +--[[-- Removes a parse function, see add_parse for adding them +@tparam string name the name of the parse to remove + +@usage-- Removing a parse +Commands.remove_parse('number-range-int') + +]] function Commands.remove_parse(name) Commands.parse_functions[name] = nil end ---- Intended to be used within other parse functions, runs a parse and returns success and new value --- @tparam string name the name of the parse to call, must be registered and cant be a function --- @tparam string input string the input to pass to the parse, will always be a but might not be the original input --- @tparam LuaPlayer player the player that is calling using the command --- @tparam function reject the reject function that was passed by the command hander --- @treturn any the new value for the input, may be nil, if nil then either there was an error or input was nil +--[[-- Intended to be used within other parse functions, runs a parse and returns success and new value +@tparam string name the name of the parse to call, must be registered parse +@tparam string input string the input to pass to the parse, must be a string but not necessarily the original input +@tparam LuaPlayer player the player that is using the command +@tparam function reject the reject function that was passed by the command hander +@treturn any the new value for the input, may be nil, if nil then either there was an error or input was nil + +@usage-- Parsing a int in a given range +local parsed_input = Commands.parse('number-range-int', '7', player, reject, 1, 10) -- valid range 1 to 10 + +]] function Commands.parse(name,input,player,reject,...) if not Commands.parse_functions[name] then return end local success,rtn = pcall(Commands.parse_functions[name],input,player,reject,...) @@ -397,10 +455,16 @@ end -- Functions that create a new command -- @section creation ---- Creates a new command object to added details to, note this does not register the command to the game --- @tparam string name the name of the command to be created --- @tparam string help the help message for the command --- @treturn Commands._prototype this will be used with other functions to generate the command functions +--[[-- Creates a new command object to added details to, note this does not register the command to the game api +@tparam string name the name of the command to be created +@tparam string help the help message for the command +@treturn Commands._prototype this will be used with other functions to generate the command functions + +@usage-- Define a new command +local command = +Commands.new_command('repeat-name', 'Will repeat you name a number of times in chat.') + +]] function Commands.new_command(name,help) local command = setmetatable({ name=name, @@ -419,16 +483,23 @@ function Commands.new_command(name,help) return command end ---- Adds a new param to the command this will be displayed in the help and used to parse the input --- @tparam string name the name of the new param that is being added to the command --- @tparam[opt=false] boolean optional is this param required for this command, these must be after all required params --- @tparam[opt=pass function through] ?string|function parse this function will take the input and return a new (or same) value --- @param[opt] ... extra args you want to pass to the parse function; for example if the parse is general use --- parse param - input: string - the input given by the user for this param --- parse param - player: LuaPlayer - the player who is using the command --- parse param - reject: function(error_message) - use this function to send a error to the user and fail running --- parse return - the value that will be passed to the command callback, must not be nil and if reject then command is not run --- @treturn Commands._prototype pass through to allow more functions to be called +--[[-- Adds a new param to the command this will be displayed in the help and used to parse the input +@tparam string name the name of the new param that is being added to the command +@tparam[opt=false] boolean optional is this param required for this command, these must be after all required params +@tparam[opt=pass function through] ?string|function parse this function will take the input and return a new (or same) value +@param[opt] ... extra args you want to pass to the parse function; for example if the parse is general use +@treturn Commands._prototype pass through to allow more functions to be called + +@usage-- Adding a param which has an parse defined +command:add_param('repeat-count', false, 'number-range-int', 1, 5) + +@usage-- Adding a param which has a custom parse, see Commands.add_parse for details +command:add_param('smiley', true, function(input, player, reject) + if not input then return end + return input:lower() == 'true' or input:lower() == 'yes' or false +end) + +]] function Commands._prototype:add_param(name,optional,parse,...) local parse_args = {...} if type(optional) ~= 'boolean' then @@ -449,10 +520,20 @@ function Commands._prototype:add_param(name,optional,parse,...) return self end ---- Adds default values to params only matters if the param is optional, if default value is a function it is called with param player --- @tparam table defaults table a keyed by the name of the param with the value as the default value {paramName=defaultValue} --- callback param - player: LuaPlayer - the player using the command, default value does not need to be a function callback --- @treturn Commands._prototype pass through to allow more functions to be called +--[[-- Add default values to params, only as an effect if the param is optional, if default value is a function it is called with acting player +@tparam table defaults table which is keyed by the name of the param and the value is the default value +@treturn Commands._prototype pass through to allow more functions to be called + +@usage-- Adding default values +command:set_defaults{ + smiley = false, + -- not in example just used to show arguments given + player_name = function(player) + return player.name + end +} + +]] function Commands._prototype:set_defaults(defaults) for name,value in pairs(defaults) do if self.params[name] then @@ -462,26 +543,32 @@ function Commands._prototype:set_defaults(defaults) return self end ---- Adds a tag to the command which is passed via the flags param to the authenticators, can be used to assign command roles or type --- @tparam string name the name of the tag to be added; used to keep flags separate --- @tparam any value the tag that you want can be anything that the authenticators are expecting --- nb: if value is nil then name will be assumed as the value and added at a numbered index --- @treturn Commands._prototype pass through to allow more functions to be called +--[[-- Adds a tag to the command which is passed via the flags param to the authenticators, can be used to assign command roles or type +@tparam string name the name of the tag to be added, set to true if no value is given +@tparam[opt=true] any value the tag that you want can be anything that the authenticators are expecting +@treturn Commands._prototype pass through to allow more functions to be called + +@usage-- Setting a custom flag +command:set_flag('admin_only', true) + +@usage-- When value is true it does not need to be given +command:set_flag('admin_only') + +]] function Commands._prototype:set_flag(name,value) - if not value then - -- value not given so name is the value - table.insert(self.flags,name) - else - -- name is given so its key: value - self.flags[name] = value - end + value = value or true + self.flags[name] = value return self end ---- Adds an alias or multiple that will also be registered with the same callback, eg /teleport can be /tp with both working --- @usage command:add_alias('aliasOne','aliasTwo','etc') --- @tparam string any ... amount of aliases that you want this command to be callable with --- @treturn Commands._prototype pass through to allow more functions to be called +--[[-- Adds an alias, or multiple, that will also be registered with the same callback, eg /teleport can be used as /tp +@tparam string any ... amount of aliases that you want this command to be callable with +@treturn Commands._prototype pass through to allow more functions to be called + +@usage-- Added multiple aliases to a command +command:add_alias('name', 'rname') + +]] function Commands._prototype:add_alias(...) for _,alias in pairs({...}) do table.insert(self.aliases,alias) @@ -490,21 +577,35 @@ function Commands._prototype:add_alias(...) return self end ---- Enables auto concatenation of any params on the end so quotes are not needed for last param --- nb: this will disable max param checking as they will be concatenated onto the end of that last param --- this can be useful for reasons or longs text, can only have one per command --- @treturn Commands._prototype pass through to allow more functions to be called +--[[-- Enables auto concatenation of any params on the end so quotes are not needed for last param +nb: this will disable max param checking as they will be concatenated onto the end of that last param +this can be useful for reasons or longs text, can only have one per command +@treturn Commands._prototype pass through to allow more functions to be called + +@usage-- Enable auto concat for a command +command:enable_auto_concat() + +]] function Commands._prototype:enable_auto_concat() self.auto_concat = true return self end ---- Adds the callback to the command and registers all aliases, params and help message with the game --- nb: this must be the last function ran on the command and must be done for the command to work --- @tparam function callback the callback for the command, will receive the player running command, and params added with add_param --- callback param - player: LuaPlayer - the player who used the command --- callback param - ... - any params which were registered with add_param in the order they where registered --- callback param - raw: string - the raw input from the user, comes after every param added with add_param +--[[-- Adds the callback to the command and registers all aliases, params and help message with the game api +nb: this must be the last function ran on the command and must be done for the command to work +@tparam function callback the callback for the command, will receive the player running command, and params added with add_param + +@usage-- Registering your command to the game api +command:register(function(player, repeat_count, smiley, _) + local msg = ') '..player.name + if smiley then msg = ':'..msg end + + for 1 = 1,repeat_count do + Command.print(1..msg) + end +end) + +]] function Commands._prototype:register(callback) -- generates a description to be used self.callback = callback @@ -538,13 +639,16 @@ end -- Functions that indicate status -- @section status ---- Sends an error message to the player and returns a constant to return to command handler to exit execution --- nb: this is for non fatal errors meaning there is no log of this event --- nb: if reject is giving as a param to the callback use that instead --- @usage return Commands.error() --- @tparam[opt] string error_message an optional error message that can be sent to the user --- @tparam[opt] string play_sound the sound to play for the error --- @treturn Commands.defines.error return this to command handler to exit execution +--[[-- Sends an error message to the player and when returned will stop exicution of the command +nb: this is for non fatal errors meaning there is no log of this event, use during register callback +@tparam[opt=''] string error_message an optional error message that can be sent to the user +@tparam[opt=utility/wire_pickup] string play_sound the sound to play for the error +@treturn Commands.defines.error return this to command handler to exit execution + +@usage-- Send an error message to the player, and stops further code running +return Commands.error('The player you selected is offline') + +]] function Commands.error(error_message,play_sound) error_message = error_message or '' player_return({'expcore-commands.command-fail',error_message},'orange_red') @@ -555,12 +659,20 @@ function Commands.error(error_message,play_sound) return Commands.defines.error end ---- Sends an error to the player and logs the error, used with pcall within command handler please avoid direct use --- nb: use error(error_message) within your callback to trigger do not trigger directly as the handler may still continue --- @tparam boolean success the success value returned from pcall, or just false to trigger error --- @tparam string command_name the name of the command this is used within the log --- @tparam string error_message the error returned by pcall or some other error, this is logged and not returned to player --- @treturn boolean the opposite of success so true means to cancel execution, used internally +--[[-- Sends an error to the player and logs the error, used with pcall within command handler please avoid direct use +nb: use error(error_message) within your callback to trigger do not trigger directly as code exictuion may still continue +@tparam boolean success the success value returned from pcall, or just false to trigger error +@tparam string command_name the name of the command this is used within the log +@tparam string error_message the error returned by pcall or some other error, this is logged and not returned to player +@treturn boolean the opposite of success so true means to cancel execution, used internally + +@usage-- Used in the command system to log handler errors +local success, err = pcall(command_data.callback, player, unpack(params)) +if Commands.internal_error(success, command_data.name, err) then + return command_log(player, command_data, 'Internal Error: Command Callback Fail', raw_params, command_event.parameter, err) +end + +]] function Commands.internal_error(success,command_name,error_message) if not success then Commands.error('Internal Error, Please contact an admin','utility/cannot_build') @@ -569,16 +681,34 @@ function Commands.internal_error(success,command_name,error_message) return not success end ---- Sends a value to the player, followed by a command complete message --- nb: either return a value from your callback to trigger or return the return of this to prevent two messages --- @tparam[opt] any value the value to return to the player, if nil then only success message returned --- @treturn Commands.defines.success return this to the command handler to prevent two success messages +--[[-- Sends a value to the player, followed by a command complete message +nb: returning any value from your callback will trigger this function, return this function to prevent duplicate messages +@tparam[opt] any value the value to return to the player, if nil then only success message returned +@treturn Commands.defines.success return this to the command handler to prevent two success messages + +@usage-- Print a custom success message +return Commands.success('Your message has been printed') + +@usage-- Returning the value has the same result +return 'Your message has been printed' + +]] function Commands.success(value) if value ~= nil then player_return(value) end player_return({'expcore-commands.command-ran'},'cyan') return Commands.defines.success end +--[[-- Sends a value to the player, different to success as this does not signal the end of your command +@function print +@tparam any value the value that you want to return to the player +@tparam table colour the colour of the message that the player sees + +@usage-- Output a message to the player +Commands.print('Your command is in progress') + +]] + -- logs command usage to file local function command_log(player,command,comment,params,raw,details) local player_name = player and player.name or '' @@ -594,6 +724,7 @@ end --- Main event function that is ran for all commands, used internally please avoid direct use -- @tparam table command_event passed directly from command event from the add_command function +-- @usage Commands.run_command(event) function Commands.run_command(command_event) local command_data = Commands.commands[command_event.name] -- player can be nil when it is the server diff --git a/expcore/common.lua b/expcore/common.lua index 983cae4d..e51b3edb 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -1,46 +1,59 @@ ---[[-- Core Module - Common Library - - Adds some commonly used functions used in many modules - @core Common-Library - @alias Common +--[[-- Core Module - Common +- Adds some commonly used functions used in many modules +@core Common +@alias Common ]] local Colours = require 'utils.color_presets' --- @dep utils.color_presets local Game = require 'utils.game' --- @dep utils.game local Util = require 'util' --- @dep util -require 'overrides.table' -require 'overrides.math' local Common = {} --- Type Checking. -- @section typeCheck ---- Asserts the argument is of type test_type --- @usage type_check('foo','string') -- return true --- @usage type_check('foo') -- return false --- @tparam any value 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 +--[[-- Asserts the argument is of type test_type +@tparam any value 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 + +@usage-- Check for a string value +local is_string = type_check(value, 'string') + +@usage-- Check for a nil value +local is_nil = type_check(value) + +]] function Common.type_check(value, test_type) return test_type and value and type(value) == test_type or not test_type and not value or false end ---- Raises an error if the value is of the wrong type --- @usage type_error('foo','number','Value must be a number') -- will raise error "Value must be a number" --- @tparam any value the value that you want to test the type of --- @tparam string test_type the type that the value should be --- @tparam string error_message the error message that is returned --- @tparam number level the level to call the error on (level = 1 means the caller) --- @treturn boolean true if no error was called +--[[-- Raises an error if the value is of the wrong type +@tparam any value the value that you want to test the type of +@tparam string test_type the type that the value should be +@tparam string error_message the error message that is returned +@tparam number level the level to call the error on (level = 1 is the caller) +@treturn boolean true if no error was called + +@usage-- Raise error if value is not a number +type_error(value, 'number', 'Value must be a number') + +]] function Common.type_error(value, test_type, error_message, level) level = level and level+1 or 2 return Common.type_check(value,test_type) or error(error_message,level) end ---- Asserts the argument is one of type test_types --- @param value the variable to check --- @param test_types the type as a table of strings --- @treturn boolean true if value is one of test_types +--[[-- Asserts the argument is one of type test_types +@param value the variable to check +@param test_types the type as a table of strings +@treturn boolean true if value is one of test_types + +@usage-- Check for a string or table +local is_string_or_table = multi_type_check(value, {'string','table'}) + +]] function Common.multi_type_check(value, test_types) local vtype = type(value) for _, arg_type in ipairs(test_types) do @@ -51,45 +64,73 @@ function Common.multi_type_check(value, test_types) return false end ---- Raises an error if the value is of the wrong type --- @usage multi_type_error('foo',{'string','table'},'Value must be a string or table') -- will raise error "Value must be a string or table" --- @tparam any value the value that you want to test the type of --- @tparam table test_types the type as a table of strings --- @tparam string error_message the error message that is returned --- @tparam number level the level to call the error on (level = 1 means the caller) --- @treturn boolean true if no error was called +--[[-- Raises an error if the value is of the wrong type +@tparam any value the value that you want to test the type of +@tparam table test_types the type as a table of strings +@tparam string error_message the error message that is returned +@tparam number level the level to call the error on (level = 1 is the caller) +@treturn boolean true if no error was called + +@usage-- Raise error if value is not a string or table +multi_type_error('foo', {'string','table'}, 'Value must be a string or table') + +]] function Common.multi_type_error(value, test_types, error_message, level) level = level and level+1 or 2 return Common.mult_type_check(value, test_types) or error(error_message,level) end ---- Raises an error when the value is the incorrect type, uses a consistent error message format --- @usage validate_argument_type('foo','number','repeat_count',2) -- will raise error "Bad argument #02 to ""; "repeat_count" is of type string expected number" --- @tparam any value the value that you want to test the type of --- @tparam string test_type the type that the value should be --- @tparam string param_name the name of the param --- @tparam number param_number the number param it is --- @treturn boolean true if no error was raised -function Common.validate_argument_type(value, test_type, param_name, param_number) +--[[-- Raises an error when the value is the incorrect type, uses a consistent error message format +@tparam any value the value that you want to test the type of +@tparam string test_type the type that the value should be +@tparam number param_number the number param it is +@tparam[opt] string param_name the name of the param +@treturn boolean true if no error was raised + +@usage-- Output: "Bad argument #2 to ""; argument is of type string expected number" +validate_argument_type(value, 'number', 2) + +@usage-- Output: "Bad argument #2 to ""; "repeat_count" is of type string expected number" +validate_argument_type(value, 'number', 2, 'repeat_count') + +]] +function Common.validate_argument_type(value, test_type, param_number, param_name) if not Common.test_type(value,test_type) then local function_name = debug.getinfo(2,'n').name or '' - local error_message = string.format('Bad argument #%2d to %q; %q is of type %s expected %s', param_number, function_name, param_name, type(value), test_type) + local error_message + if param_name then + error_message = string.format('Bad argument #%d to %q; %q is of type %s expected %s', param_number, function_name, param_name, type(value), test_type) + else + error_message = string.format('Bad argument #%d to %q; argument is of type %s expected %s', param_number, function_name, type(value), test_type) + end return error(error_message,3) end return true end ---- Raises an error when the value is the incorrect type, uses a consistent error message format --- @usage validate_argument_type('foo',{'string','table'},'repeat_count',2) -- will raise error "Bad argument #02 to ""; "repeat_count" is of type string expected string or table" --- @tparam any value the value that you want to test the type of --- @tparam string test_types the types that the value should be --- @tparam string param_name the name of the param --- @tparam number param_number the number param it is --- @treturn boolean true if no error was raised -function Common.validate_argument_multi_type(value, test_types, param_name, param_number) +--[[-- Raises an error when the value is the incorrect type, uses a consistent error message format +@tparam any value the value that you want to test the type of +@tparam string test_types the types that the value should be +@tparam number param_number the number param it is +@tparam[opt] string param_name the name of the param +@treturn boolean true if no error was raised + +@usage-- Output: "Bad argument #2 to ""; argument is of type number expected string or table" +validate_argument_type(value, {'string','table'}, 2) + +@usage-- Output: "Bad argument #2 to ""; "player" is of type number expected string or table" +validate_argument_type(value, {'string','table'}, 2, 'player') + +]] +function Common.validate_argument_multi_type(value, test_types, param_number, param_name) if not Common.multi_type_check(value,test_types) then local function_name = debug.getinfo(2,'n').name or '' - local error_message = string.format('Bad argument #%2d to %q; %q is of type %s expected %s', param_number, function_name, param_name, type(value), table.concat(test_types,' or ')) + local error_message + if param_name then + error_message = string.format('Bad argument #%2d to %q; %q is of type %s expected %s', param_number, function_name, param_name, type(value), table.concat(test_types,' or ')) + else + error_message = string.format('Bad argument #%2d to %q; argument is of type %s expected %s', param_number, function_name, type(value), table.concat(test_types,' or ')) + end return error(error_message,3) end return true @@ -116,10 +157,15 @@ end --- Value Returns. -- @section valueReturns ---- Tests if a string contains a given substring. --- @tparam string s the string to check for the substring --- @tparam string contains the substring to test for --- @treturn boolean true if the substring was found in the string +--[[-- Tests if a string contains a given substring. +@tparam string s the string to check for the substring +@tparam string contains the substring to test for +@treturn boolean true if the substring was found in the string + +@usage-- Test if a string contains a sub string +local found = string_contains(str, 'foo') + +]] function Common.string_contains(s, contains) return s and string.find(s, contains) ~= nil end @@ -127,82 +173,104 @@ end --[[-- Used to resolve a value that could also be a function returning that value @tparam any value the value which you want to test is not nil and if it is a function then call the function @treturn any the value given or returned by value if it is a function + @usage-- Default value handling -- if default value is not a function then it is returned --- if it is a function then it is called with the first argument being self -local value = Common.resolve_value(self.defaut_value,self) +-- if default value is a function then it is called with the first argument being self +local value = Common.resolve_value(self.defaut_value, self) + ]] function Common.resolve_value(value,...) - if value then - if type(value) == 'function' then - return value(...) - else - return value - end - end -end - ---- Returns a valid string with the name of the actor of a command. --- @treturns string the name of the current actor -function Common.get_actor() - return game.player and game.player.name or '' + return value and type(value) == 'function' and value(...) or value end --- Converts a varible into its boolean value, nil and false return false -- @treturn boolean the boolean form of the varible +-- @usage local bool = cast_bool(var) function Common.cast_bool(var) return var and true or false end --- Returns either the second or third argument based on the first argument +-- @usage ternary(input_string == 'test', 'Input is test', 'Input is not test') function Common.ternary(c, t, f) return c and t or f end --- Returns a string for a number with comma seperators +-- @usage comma_value(input_number) function Common.comma_value(n) -- credit http://richard.warburton.it local left, num, right = string.match(n, '^([^%d]*%d)(%d*)(.-)$') return left .. (num:reverse():gsub('(%d%d%d)', '%1,'):reverse()) .. right end ---- Sets a table element to value while also returning value. --- @param tbl table to change the element of --- @param key string --- @param value nil|boolean|number|string|table to set the element to --- @return value +--[[-- Sets a table element to value while also returning value. +@tparam table tbl to change the element of +@tparam string key the key to set the value of +@tparam any value the value to set the key as +@treturn any the value that was set + +@usage-- Set and return value +local value = set_and_return(players, player.name, player.online_time) + +]] function Common.set_and_return(tbl, key, value) tbl[key] = value return value end ---- Writes a table object to a file in json format --- @tparam string path the path of the file to write include / to use dir --- @tparam table tbl the table that will be converted to a json string and wrote to file +--[[-- Writes a table object to a file in json format +@tparam string path the path of the file to write include / to use dir +@tparam table tbl the table that will be converted to a json string and wrote to file + +@usage-- Write a lua table as a json to script-outpt/dump +write_json('dump', tbl) + +]] function Common.write_json(path,tbl) game.write_file(path,game.table_to_json(tbl)..'\n',true,0) end ---- Calls a require that will not error if the file is not found --- @usage local file = opt_require('file.not.present') -- will not cause any error --- @tparam string path the path that you want to require --- @return the returns from that file or nil, error if not loaded +--[[-- Calls a require that will not error if the file is not found +@usage local file = opt_require('file.not.present') -- will not cause any error +@tparam string path the path that you want to require +@return the returns from that file or nil, error if not loaded + +@usage-- Require a file without causing errors, for when a file might not exist +local Module = opt_require 'expcore.common' + +]] function Common.opt_require(path) local success, rtn = pcall(require,path) if success then return rtn else return nil,rtn end end ---- Returns a desync safe file path for the current file --- @tparam[opt=0] number offset the offset in the stack to get, 0 is current file --- @treturn string the file path +--[[-- Returns a desync safe file path for the current file +@tparam[opt=0] number offset the offset in the stack to get, 0 is current file +@treturn string the file path + +@usage-- Get the current file path +local file_path = get_file_path() + +]] function Common.get_file_path(offset) offset = offset or 0 return debug.getinfo(offset+2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) end ---- Converts a table to an enum --- @tparam table tbl table the that will be converted --- @treturn table the new table that acts like an enum +--[[-- Converts a table to an enum +@tparam table tbl table the that will be converted +@treturn table the new table that acts like an enum + +@usage-- Make an enum +local colors = enum{ + 'red', + 'green', + 'blue' +} + +]] function Common.enum(tbl) local rtn = {} for k,v in pairs(tbl) do @@ -221,12 +289,23 @@ function Common.enum(tbl) return rtn end ---- Returns the closest match to the input --- @tparam table options table a of options for the auto complete --- @tparam string input string the input that will be completed --- @tparam[opt=false] boolean use_key when true the keys of options will be used as the options --- @tparam[opt=false] boolean rtn_key when true the the key will be returned rather than the value --- @return the list item found that matches the input +--[[-- Returns the closest match to the input +@tparam table options table a of options for the auto complete +@tparam string input string the input that will be completed +@tparam[opt=false] boolean use_key when true the keys of options will be used as the options +@tparam[opt=false] boolean rtn_key when true the the key will be returned rather than the value +@return the list item found that matches the input + +@usage-- Get the element that includes "foo" +local value = auto_complete(tbl, "foo") + +@usage-- Get the element with a key that includes "foo" +local value = auto_complete(tbl, "foo", true) + +@usage-- Get the key with that includes "foo" +local key = auto_complete(tbl, "foo", true, true) + +]] function Common.auto_complete(options,input,use_key,rtn_key) local rtn = {} if type(input) ~= 'string' then return end @@ -234,40 +313,65 @@ function Common.auto_complete(options,input,use_key,rtn_key) for key,value in pairs(options) do local check = use_key and key or value if Common.string_contains(string.lower(check),input) then - local result = rtn_key and key or value - table.insert(rtn,result) + return rtn_key and key or value end end - return rtn[1] end --- Formating. -- @section formating ---- Returns a message with valid chat tags to change its colour --- @tparam string message the message that will be in the output --- @tparam table color a color which contains r,g,b as its keys --- @treturn string the message with the color tags included +--[[-- Returns a valid string with the name of the actor of a command. +@tparam string player_name the name of the player to use rather than server, used only if game.player is nil +@treturn string the name of the current actor + +@usage-- Get the current actor +local player_name = get_actor() + +]] +function Common.get_actor(player_name) + return game.player and game.player.name or player_name or '' +end + +--[[-- Returns a message with valid chat tags to change its colour +@tparam string message the message that will be in the output +@tparam table color a color which contains r,g,b as its keys +@treturn string the message with the color tags included + +@usage-- Use factorio tags to color a chat message +local message = format_chat_colour('Hello, World!', { r=355, g=100, b=100 }) + +]] function Common.format_chat_colour(message,color) color = color or Colours.white local color_tag = '[color='..math.round(color.r,3)..','..math.round(color.g,3)..','..math.round(color.b,3)..']' return string.format('%s%s[/color]',color_tag,message) end ---- Returns a message with valid chat tags to change its colour, using localization --- @tparam ?string|table message the message that will be in the output --- @tparam table color a color which contains r,g,b as its keys --- @treturn table the message with the color tags included +--[[-- Returns a message with valid chat tags to change its colour, using localization +@tparam ?string|table message the message that will be in the output +@tparam table color a color which contains r,g,b as its keys +@treturn table the message with the color tags included + +@usage-- Use factorio tags and locale strings to color a chat message +local message = format_chat_colour_localized('Hello, World!', { r=355, g=100, b=100 }) + +]] function Common.format_chat_colour_localized(message,color) color = color or Colours.white color = math.round(color.r,3)..','..math.round(color.g,3)..','..math.round(color.b,3) return {'color-tag',color,message} end ---- Returns the players name in the players color --- @tparam LuaPlayer player the player to use the name and color of --- @tparam[opt=false] boolean raw_string when true a is returned rather than a localized string --- @treturn table the players name with tags for the players color +--[[-- Returns the players name in the players color +@tparam LuaPlayer player the player to use the name and color of +@tparam[opt=false] boolean raw_string when true a string is returned rather than a localized string +@treturn table the players name with tags for the players color + +@usage-- Format a players name using the players color as a string +local message = format_chat_player_name(game.player, true) + +]] function Common.format_chat_player_name(player,raw_string) player = Game.get_player_from_any(player) local player_name = player and player.name or '' @@ -279,13 +383,21 @@ function Common.format_chat_player_name(player,raw_string) end 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 value 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 +--[[-- Will return a value of any type to the player/server console, allows colour for in-game players +@tparam any value a 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 + +@usage-- Return a value to the current actor, rcon included +player_return('Hello, World!') + +@usage-- Return a value to the current actor, with color +player_return('Hello, World!', 'green') + +@usage-- Return to a player other than the current +player_return('Hello, World!', nil, player) + +]] function Common.player_return(value,colour,player) colour = Common.type_check(colour,'table') and colour or Colours[colour] ~= Colours.white and Colours[colour] or Colours.white player = player or game.player @@ -320,14 +432,26 @@ function Common.player_return(value,colour,player) else rcon.print(returnAsString) end end ---- Formats tick into a clean format, denominations from highest to lowest --- long will use words rather than letters +--[[-- Formats tick into a clean format, denominations from highest to lowest -- time will use : separates --- string will return a string not a locale string -- when a denomination is false it will overflow into the next one --- @tparam number ticks the number of ticks that represents a time --- @tparam table options table a of options to use for the format --- @treturn string a locale string that can be used +@tparam number ticks the number of ticks that represents a time +@tparam table options table a of options to use for the format +@treturn string a locale string that can be used + +@usage-- Output: "0h 5m" +local time = format_time(18000, { hours=true, minutes=true, string=true }) + +@usage-- Output: "0 hours and 5 minutes" +local time = format_time(18000, { hours=true, minutes=true, string=true, long=true }) + +@usage-- Output: "00:05:00" +local time = format_time(18000, { hours=true, minutes=true, seconds=true, string=true }) + +@usage-- Output: "--:--:--" +local time = format_time(18000, { hours=true, minutes=true, seconds=true, string=true, null=true }) + +]] function Common.format_time(ticks,options) -- Sets up the options options = options or { @@ -415,12 +539,18 @@ end --- Factorio. -- @section factorio ---- Moves items to the position and stores them in the closest entity of the type given --- @tparam table items items which are to be added to the chests, ['name']=count --- @tparam[opt=navies] LuaSurface surface the surface that the items will be moved to --- @tparam[opt={0,0}] table position the position that the items will be moved to {x=100,y=100} --- @tparam[opt=32] number radius the radius in which the items are allowed to be placed --- @tparam[opt=iron-chest] string chest_type the chest type that the items should be moved into +--[[-- Moves items to the position and stores them in the closest entity of the type given +@tparam table items items which are to be added to the chests, ['name']=count +@tparam[opt=navies] LuaSurface surface the surface that the items will be moved to +@tparam[opt={0,0}] table position the position that the items will be moved to {x=100,y=100} +@tparam[opt=32] number radius the radius in which the items are allowed to be placed +@tparam[opt=iron-chest] string chest_type the chest type that the items should be moved into +@treturn LuaEntity the last chest that had items inserted into it + +@usage-- Copy all the items in a players inventory and place them in chests at {0,0} +move_items(game.player.get_main_inventory().get_contents()) + +]] function Common.move_items(items,surface,position,radius,chest_type) chest_type = chest_type or 'iron-chest' surface = surface or game.surfaces[1] @@ -466,14 +596,19 @@ function Common.move_items(items,surface,position,radius,chest_type) return last_chest end ---[[-- https://github.com/Refactorio/RedMew/blob/9184b2940f311d8c9c891e83429fc57ec7e0c4a2/map_gen/maps/diggy/debug.lua#L31 - Prints a colored value on a location. - @param value between -1 and 1 - @param surface LuaSurface - @param position Position {x, y} - @param scale float - @param offset float - @param immutable bool if immutable, only set, never do a surface lookup, values never change +--[[-- Prints a colored value on a location, color is based on the value. +nb: src is below but the gradent has been edited +https://github.com/Refactorio/RedMew/blob/9184b2940f311d8c9c891e83429fc57ec7e0c4a2/map_gen/maps/diggy/debug.lua#L31 +@tparam number value the value to show must be between -1 and 1, scale can be used to achive this +@tparam LuaSurface surface the surface to palce the value on +@tparam table position {x, y} the possition to palce the value at +@tparam[opt=1] number scale how much to scale the colours by +@tparam[opt=0] number offset the offset in the +x +y direction +@tparam[opt=false] boolean immutable if immutable, only set, never do a surface lookup, values never change + +@usage-- Place a 0 at {0,0} +print_grid_value(0, game.player.surface, { x=0, y=0 }) + ]] function Common.print_grid_value(value, surface, position, scale, offset, immutable) local is_string = type(value) == 'string' @@ -488,23 +623,9 @@ function Common.print_grid_value(value, surface, position, scale, offset, immuta scale = scale or 1 offset = offset or 0 position = {x = position.x + offset, y = position.y + offset} - local r = math.max(1, value) / scale - local g = 1 - math.abs(value) / scale - local b = math.min(1, value) / scale - - if (r > 0) then - r = 0 - end - - if (b < 0) then - b = 0 - end - - if (g < 0) then - g = 0 - end - - r = math.abs(r) + local r = math.clamp(-value/scale, 0, 1) + local g = math.clamp(1-math.abs(value)/scale, 0, 1) + local b = math.clamp(value/scale, 0, 1) color = { r = r, g = g, b = b} @@ -534,81 +655,13 @@ function Common.print_grid_value(value, surface, position, scale, offset, immuta }.active = false end ---[[-- - Prints a colored value on a location. When given a color_value and a delta_color, - will change the color of the text from the base to base + value * delta. This will - make the color of the text range from 'base_color' to 'base_color + delta_color' - as the color_value ranges from 0 to 1 - @param value of number to be displayed - @param surface LuaSurface - @param position Position {x, y} - @param offset float position offset - @param immutable bool if immutable, only set, never do a surface lookup, values never change - @param color_value float How far along the range of values of colors the value is to be displayed - @param base_color {r,g,b} The color for the text to be if color_value is 0 - @param delta_color {r,g,b} The amount to correct the base_color if color_value is 1 - @param under_bound {r,g,b} The color to be used if color_value < 0 - @param over_bound {r,g,b} The color to be used if color_value > 1 +--[[-- Clears all flying text entities on a surface +@tparam LuaSurface surface the surface to clear + +@usage-- Remove all flying text on the surface +clear_flying_text(game.player.surface) + ]] -function Common.print_colored_grid_value(value, surface, position, offset, immutable, - color_value, base_color, delta_color, under_bound, over_bound) - local is_string = type(value) == 'string' - -- default values: - local color = base_color or Colours.white - local d_color = delta_color or Colours.black - local u_color = under_bound or color - local o_color = over_bound or color - - if (color_value < 0) then - color = u_color - elseif (color_value > 1) then - color = o_color - else - color = { - r = color.r + color_value * d_color.r, - g = color.g + color_value * d_color.g, - b = color.b + color_value * d_color.b - } - end - - local text = value - - if type(immutable) ~= 'boolean' then - immutable = false - end - - if not is_string then - offset = offset or 0 - position = {x = position.x + offset, y = position.y + offset} - - -- round at precision of 2 - text = math.floor(100 * value) * 0.01 - - if (0 == text) then - text = '0.00' - end - end - - if not immutable then - local text_entity = surface.find_entity('flying-text', position) - - if text_entity then - text_entity.text = text - text_entity.color = color - return - end - end - - surface.create_entity{ - name = 'flying-text', - color = color, - text = text, - position = position - }.active = false -end - ---- Clears all flying text entities on a surface --- @tparam LuaSurface surface the surface to clear function Common.clear_flying_text(surface) local entities = surface.find_entities_filtered{name ='flying-text'} for _,entity in pairs(entities) do diff --git a/expcore/gui.lua b/expcore/gui.lua index eaa22047..70817151 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -1 +1 @@ -return require 'expcore.gui.require' \ No newline at end of file +return require 'expcore.gui._require' \ No newline at end of file diff --git a/expcore/gui/_require.lua b/expcore/gui/_require.lua new file mode 100644 index 00000000..306c354d --- /dev/null +++ b/expcore/gui/_require.lua @@ -0,0 +1,131 @@ +--[[-- Core Module - Gui +- Used to simplify gui creation using factory functions called element defines +@core Gui +@alias Gui + +@usage-- To draw your element you only need to call the factory function +-- You are able to pass any other arguments that are used in your custom functions but the first is always the parent element +local example_button_element = example_button(parent_element) + +@usage-- Making a factory function for a button with the caption "Example Button" +-- This method has all the same features as LuaGuiElement.add +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button' +} + +@usage-- Making a factory function for a button which is contained within a flow +-- This method is for when you still want to register event handlers but cant use the table method +local example_flow_with_button = +Gui.element(function(event_trigger,parent,...) + -- ... shows that all other arguments from the factory call are passed to this function + -- Here we are adding a flow which we will then later add a button to + local flow = + parent.add{ -- paraent is the element which is passed to the factory function + name = 'example_flow', + type = 'flow' + } + + -- Now we add the button to the flow that we created earlier + local element = + flow.add{ + name = event_trigger, -- event_trigger should be the name of any elements you want to trigger your event handlers + type = 'button', + caption = 'Example Button' + } + + -- You must return a new element, this is so styles can be applied and returned to the caller + -- You may return any of your elements that you added, consider the context in which it will be used for which should be returned + return element +end) + +@usage-- Styles can be added to any element define, simplest way mimics LuaGuiElement.style[key] = value +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here +} +:style{ + height = 25, -- same as element.style.height = 25 + width = 100 -- same as element.style.width = 25 +} + +@usage-- Styles can also have a custom function when the style is dynamic and depends on other factors +-- Use this method if your style is dynamic and depends on other factors +local example_button = +Gui.element{ + type = 'button', + caption = 'Example Button', + style = 'forward_button' -- factorio styles can be applied here +} +:style(function(style,element,...) + -- style is the current style object for the elemenent + -- element is the element that is being changed + -- ... shows that all other arguments from the factory call are passed to this function + local player = game.players[element.player_index] + style.height = 25 + style.width = 100 + style.font_color = player.color +end) + +@usage-- You are able to register event handlers to your elements, these can be factorio events or custom ones +-- All events are checked to be valid before raising any handlers, this means element.valid = true and player.valid = true +Gui.element{ + type = 'button', + caption = 'Example Button' +} +:on_click(function(player,element,event) + -- player is the player who interacted with the element to cause the event + -- element is a refrence to the element which caused the event + -- event is a raw refrence to the event data if player and element are not enough + player.print('Clicked: '..element.name) +end) + +@usage-- Example from core_defines, Gui.core_defines.hide_left_flow, called like: hide_left_flow(parent_element) +--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible +-- @element hide_left_flow +local hide_left_flow = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/close_black', + style = 'tool_button', + tooltip = {'expcore-gui.left-button-tooltip'} +} +:style{ + padding = -3, + width = 18, + height = 20 +} +:on_click(function(player,_,_) + Gui.hide_left_flow(player) +end) + +@usage-- Eample from defines, Gui.alignment, called like: Gui.alignment(parent, name, horizontal_align, vertical_align) +-- Notice how _ are used to blank arguments that are not needed in that context and how they line up with above +Gui.alignment = +Gui.element(function(_,parent,name,_,_) + return parent.add{ + name = name or 'alignment', + type = 'flow', + } +end) +:style(function(style,_,_,horizontal_align,vertical_align) + style.padding = {1,2} + style.vertical_align = vertical_align or 'center' + style.horizontal_align = horizontal_align or 'right' + style.vertically_stretchable = style.vertical_align ~= 'center' + style.horizontally_stretchable = style.horizontal_align ~= 'center' +end) + +]] + +local Gui = require 'expcore.gui.prototype' +require 'expcore.gui.core_defines' +require 'expcore.gui.top_flow' +require 'expcore.gui.left_flow' +require 'expcore.gui.helper_functions' +require 'expcore.gui.defines' + +return Gui \ No newline at end of file diff --git a/expcore/gui/core_defines.lua b/expcore/gui/core_defines.lua index 8ae38fbe..0a545a34 100644 --- a/expcore/gui/core_defines.lua +++ b/expcore/gui/core_defines.lua @@ -4,7 +4,7 @@ ]] local Gui = require 'expcore.gui.prototype' -local Event = require 'utils.event' --- @dep utils.event +local Event = require 'utils.event' --- Core Defines. -- @section coreDefines diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 03fba9ab..f57dac1a 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -4,7 +4,7 @@ ]] local Gui = require 'expcore.gui.prototype' -local mod_gui = require 'mod-gui' --- @dep mod-gui +local mod_gui = require 'mod-gui' local hide_left_flow = Gui.core_defines.hide_left_flow.name @@ -82,7 +82,7 @@ end --[[-- Draw all the left elements onto the left flow, internal use only with on join @tparam LuaPlayer player the player that you want to draw the elements for -@usage Draw all the left elements +@usage-- Draw all the left elements Gui.draw_left_flow(player) ]] diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 526d27b0..f7803602 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -1,152 +1,26 @@ --[[-- Core Module - Gui - Used to simplify gui creation using factory functions called element defines -@core Gui -@alias Gui - -@usage-- To draw your element you only need to call the factory function --- You are able to pass any other arguments that are used in your custom functions but the first is always the parent element -local example_button_element = example_button(parent_element) - -@usage-- Making a factory function for a button with the caption "Example Button" --- This method has all the same features as LuaGuiElement.add -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button' -} - -@usage-- Making a factory function for a button which is contained within a flow --- This method is for when you still want to register event handlers but cant use the table method -local example_flow_with_button = -Gui.element(function(event_trigger,parent,...) - -- ... shows that all other arguments from the factory call are passed to this function - -- Here we are adding a flow which we will then later add a button to - local flow = - parent.add{ -- paraent is the element which is passed to the factory function - name = 'example_flow', - type = 'flow' - } - - -- Now we add the button to the flow that we created earlier - local element = - flow.add{ - name = event_trigger, -- event_trigger should be the name of any elements you want to trigger your event handlers - type = 'button', - caption = 'Example Button' - } - - -- You must return a new element, this is so styles can be applied and returned to the caller - -- You may return any of your elements that you added, consider the context in which it will be used for which should be returned - return element -end) - -@usage-- Styles can be added to any element define, simplest way mimics LuaGuiElement.style[key] = value -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button', - style = 'forward_button' -- factorio styles can be applied here -} -:style{ - height = 25, -- same as element.style.height = 25 - width = 100 -- same as element.style.width = 25 -} - -@usage-- Styles can also have a custom function when the style is dynamic and depends on other factors --- Use this method if your style is dynamic and depends on other factors -local example_button = -Gui.element{ - type = 'button', - caption = 'Example Button', - style = 'forward_button' -- factorio styles can be applied here -} -:style(function(style,element,...) - -- style is the current style object for the elemenent - -- element is the element that is being changed - -- ... shows that all other arguments from the factory call are passed to this function - local player = game.players[element.player_index] - style.height = 25 - style.width = 100 - style.font_color = player.color -end) - -@usage-- You are able to register event handlers to your elements, these can be factorio events or custom ones --- All events are checked to be valid before raising any handlers, this means element.valid = true and player.valid = true -Gui.element{ - type = 'button', - caption = 'Example Button' -} -:on_click(function(player,element,event) - -- player is the player who interacted with the element to cause the event - -- element is a refrence to the element which caused the event - -- event is a raw refrence to the event data if player and element are not enough - player.print('Clicked: '..element.name) -end) - -@usage-- Example from core_defines, Gui.core_defines.hide_left_flow, called like: hide_left_flow(parent_element) ---- Button which hides the elements in the left flow, shows inside the left flow when frames are visible --- @element hide_left_flow -local hide_left_flow = -Gui.element{ - type = 'sprite-button', - sprite = 'utility/close_black', - style = 'tool_button', - tooltip = {'expcore-gui.left-button-tooltip'} -} -:style{ - padding = -3, - width = 18, - height = 20 -} -:on_click(function(player,_,_) - Gui.hide_left_flow(player) -end) - -@usage-- Eample from defines, Gui.alignment, called like: Gui.alignment(parent, name, horizontal_align, vertical_align) --- Notice how _ are used to blank arguments that are not needed in that context and how they line up with above -Gui.alignment = -Gui.element(function(_,parent,name,_,_) - return parent.add{ - name = name or 'alignment', - type = 'flow', - } -end) -:style(function(style,_,_,horizontal_align,vertical_align) - style.padding = {1,2} - style.vertical_align = vertical_align or 'center' - style.horizontal_align = horizontal_align or 'right' - style.vertically_stretchable = style.vertical_align ~= 'center' - style.horizontally_stretchable = style.horizontal_align ~= 'center' -end) - +@module Gui ]] local Event = require 'utils.event' --- @dep utils.event local Gui = { --- The current highest uid that is being used by a define, will not increase during runtime - -- @field uid uid = 0, --- String indexed table used to avoid conflict with custom event names, similar to how defines.events works - -- @table events events = {}, --- Uid indexed array that stores all the factory functions that were defined, no new values will be added during runtime - -- @table defines defines = {}, --- An string indexed table of all the defines which are used by the core of the gui system, used for internal refrence - -- @table core_defines core_defines = {}, --- Used to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debuging - -- @table file_paths file_paths = {}, --- Used to store extra infomation about elements as they get defined such as the params used and event handlers registered to them - -- @table debug_info debug_info = {}, --- The prototype used to store the functions of an element define - -- @table _prototype_element _prototype_element = {}, --- The prototype metatable applied to new element defines - -- @table _mt_element _mt_element = { __call = function(self,parent,...) local element = self._draw(self.name,parent,...) @@ -365,50 +239,86 @@ end --- Called when the player opens a GUI. -- @tparam function handler the event handler which will be called +-- @usage element_define:on_open(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_open = event_handler_factory(defines.events.on_gui_opened) --- Called when the player closes the GUI they have open. -- @tparam function handler the event handler which will be called +-- @usage element_define:on_close(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_close = event_handler_factory(defines.events.on_gui_closed) --- Called when LuaGuiElement is clicked. -- @tparam function handler the event handler which will be called +-- @usage element_define:on_click(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click) --- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield. -- @tparam function handler the event handler which will be called +-- @usage element_define:on_confirmed(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed) --- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons). -- @tparam function handler the event handler which will be called +-- @usage element_define:on_checked_changed(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed) --- Called when LuaGuiElement element value is changed (related to choose element buttons). -- @tparam function handler the event handler which will be called +-- @usage element_define:on_elem_changed(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed) --- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen). -- @tparam function handler the event handler which will be called +-- @usage element_define:on_location_changed(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed) --- Called when LuaGuiElement selected tab is changed (related to tabbed-panes). -- @tparam function handler the event handler which will be called +-- @usage element_define:on_tab_changed(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed) --- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes). -- @tparam function handler the event handler which will be called +-- @usage element_define:on_selection_changed(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed) --- Called when LuaGuiElement switch state is changed (related to switches). -- @tparam function handler the event handler which will be called +-- @usage element_define:on_switch_changed(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed) --- Called when LuaGuiElement text is changed by the player. -- @tparam function handler the event handler which will be called +-- @usage element_define:on_text_changed(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed) --- Called when LuaGuiElement slider value is changed (related to the slider element). -- @tparam function handler the event handler which will be called +-- @usage element_define:on_value_changed(function(event) +-- event.player.print(table.inspect(event)) +--end) Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed) -- Module return diff --git a/expcore/gui/require.lua b/expcore/gui/require.lua deleted file mode 100644 index 26fcf0d6..00000000 --- a/expcore/gui/require.lua +++ /dev/null @@ -1,8 +0,0 @@ -local Gui = require 'expcore.gui.prototype' -require 'expcore.gui.core_defines' -require 'expcore.gui.top_flow' -require 'expcore.gui.left_flow' -require 'expcore.gui.helper_functions' -require 'expcore.gui.defines' - -return Gui \ No newline at end of file diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua index f06dea2e..1f50fc47 100644 --- a/expcore/gui/top_flow.lua +++ b/expcore/gui/top_flow.lua @@ -145,7 +145,7 @@ function Gui.toolbar_button(sprite,tooltip,authenticator) end --[[-- Styles a top flow button depending on the state given -@tparam LuaGuiElement the button element to style +@tparam LuaGuiElement button the button element to style @tparam boolean state The state the button is in @usage-- Sets the button to the visible style diff --git a/expcore/permission_groups.lua b/expcore/permission_groups.lua index 136717e0..5b88331f 100644 --- a/expcore/permission_groups.lua +++ b/expcore/permission_groups.lua @@ -1,29 +1,25 @@ --[[-- Core Module - Permission Groups - - Permission group making for factorio so you never have to make one by hand again - @core Permissions-Groups - @alias Permissions_Groups +- Permission group making for factorio so you never have to make one by hand again +@core Groups +@alias Permissions_Groups - @usage ----- Example Group (Allow All) +@usage--- Example Group (Allow All) +-- here we will create an admin group however we do not want them to use the map editor or mess with the permission groups +Permission_Groups.new_group('Admin') -- this defines a new group called "Admin" +:allow_all() -- this makes the default to allow any input action unless set other wise +:disallow{ -- here we disallow the input action we don't want them to use + 'add_permission_group', + 'delete_permission_group', + 'import_permissions_string', + 'map_editor_action', + 'toggle_map_editor' +} - -- here we will create an admin group however we do not want them to use the map editor or mess with the permission groups - Permission_Groups.new_group('Admin') -- this defines a new group called "Admin" - :allow_all() -- this makes the default to allow any input action unless set other wise - :disallow{ -- here we disallow the input action we don't want them to use - 'add_permission_group', - 'delete_permission_group', - 'import_permissions_string', - 'map_editor_action', - 'toggle_map_editor' - } - - @usage ----- Example Group (Disallow All) - - -- here we will create a group that cant do anything but talk in chat - Permission_Groups.new_group('Restricted') -- this defines a new group called "Restricted" - :disallow_all() -- this makes the default to disallow any input action unless set other wise - :allow('write_to_console') -- here we allow them to chat, {} can be used here if we had more than one action +@usage--- Example Group (Disallow All) +-- here we will create a group that cant do anything but talk in chat +Permission_Groups.new_group('Restricted') -- this defines a new group called "Restricted" +:disallow_all() -- this makes the default to disallow any input action unless set other wise +:allow('write_to_console') -- here we allow them to chat, {} can be used here if we had more than one action ]] @@ -55,9 +51,14 @@ Permissions_Groups.async_token_remove_from_permission_group = remove_from_permis -- Functions that get permission groups -- @section getters ---- Defines a new permission group that can have it actions set in the config --- @tparam string name the name of the new group --- @treturn Permissions_Groups._prototype the new group made with function to allow and disallow actions +--[[-- Defines a new permission group that can have it actions set in the config +@tparam string name the name of the new group +@treturn Permissions_Groups._prototype the new group made with function to allow and disallow actions + +@usage-- Defining a new permission group +Groups.new_group('Admin') + +]] function Permissions_Groups.new_group(name) local group = setmetatable({ name=name, @@ -70,16 +71,26 @@ function Permissions_Groups.new_group(name) return group end ---- Returns the group with the given name, case sensitive --- @tparam string name the name of the group to get --- @treturn ?Permissions_Groups._prototype|nil the group with that name or nil if non found +--[[-- Returns the group with the given name, case sensitive +@tparam string name the name of the group to get +@treturn ?Permissions_Groups._prototype|nil the group with that name or nil if non found + +@usage-- Getting a permision group +local admin_group = Groups.get_group_by_name('Admin') + +]] function Permissions_Groups.get_group_by_name(name) return Permissions_Groups.groups[name] end ---- Returns the group that a player is in --- @tparam LuaPlayer player the player to get the group of can be name index etc --- @treturn ?Permissions_Groups._prototype|nil the group with that player or nil if non found +--[[-- Returns the group that a player is in +@tparam LuaPlayer player the player to get the group of can be name index etc +@treturn ?Permissions_Groups._prototype|nil the group with that player or nil if non found + +@usage-- Get your permission group +local group = Groups.get_group_from_player(game.player) + +]] function Permissions_Groups.get_group_from_player(player) player = Game.get_player_from_any(player) if not player then return end @@ -93,43 +104,27 @@ end -- Functions that control all groups -- @section players ---- Reloads/creates all permission groups and sets them to they configured state +--[[-- Reloads/creates all permission groups and sets them to they configured state + +@usage-- Reload the permission groups, used internally +Groups.reload_permissions() + +]] function Permissions_Groups.reload_permissions() for _,group in pairs(Permissions_Groups.groups) do group:create() end end ---- Removes all permissions from every permission group except for "Default" and any passed as exempt --- @tparam ?string|Array exempt groups that you want to be except, "Default" is always exempt --- @treturn number the number of groups that had they permissions removed -function Permissions_Groups.lockdown_permissions(exempt) - local count = 0 - if type(exempt) ~= 'table' then - exempt = {exempt} - end - for _,group in pairs(exempt) do - if type(group) == 'string' then - exempt[group:lower()] = true - elseif type(group) == 'table' then - exempt[group.name:lower()] = true - end - end - for _,group in pairs(game.permissions.groups) do - if not exempt[group.name:lower()] and not group.name == 'Default' then - count = count +1 - for _,action in pairs(defines.input_action) do - group.set_allows_action(action,false) - end - end - end - return count -end +--[[-- Sets a player's group to the one given, a player can only have one group at a time +@tparam LuaPlayer player the player to effect can be name index etc +@tparam string group the name of the group to give to the player +@treturn boolean true if the player was added successfully, false other wise ---- Sets a player's group to the one given, a player can only have one group at a time --- @tparam LuaPlayer player the player to effect can be name index etc --- @tparam string group the name of the group to give to the player --- @treturn boolean true if the player was added successfully, false other wise +@usage-- Set your permission group +Groups.set_player_group(game.player, 'Admin') + +]] function Permissions_Groups.set_player_group(player,group) player = Game.get_player_from_any(player) group = Permissions_Groups.get_group_by_name(group) @@ -142,10 +137,15 @@ end -- Functions that control group actions -- @section actions ---- Sets the allow state of an action for this group, used internally but is safe to use else where --- @tparam ?string|defines.input_action action the action that you want to set the state of --- @tparam boolean state the state that you want to set it to, true = allow, false = disallow --- @treturn Permissions_Groups._prototype returns self so function can be chained +--[[-- Sets the allow state of an action for this group, used internally but is safe to use else where +@tparam ?string|defines.input_action action the action that you want to set the state of +@tparam boolean state the state that you want to set it to, true = allow, false = disallow +@treturn Permissions_Groups._prototype returns self so function can be chained + +@usage-- Set an action to be disalowed +group:set_action('toggle_map_editor', false) + +]] function Permissions_Groups._prototype:set_action(action,state) if type(action) == 'string' then action = defines.input_action[action] @@ -154,9 +154,16 @@ function Permissions_Groups._prototype:set_action(action,state) return self end ---- Sets an action or actions to be allowed for this group even with disallow_all triggered, Do not use in runtime --- @tparam string|Array actions the action or actions that you want to allow for this group --- @treturn Permissions_Groups._prototype returns self so function can be chained +--[[-- Sets an action or actions to be allowed for this group even with disallow_all triggered, Do not use in runtime +@tparam string|Array actions the action or actions that you want to allow for this group +@treturn Permissions_Groups._prototype returns self so function can be chained + +@usage-- Allow some actions +group:allow{ + 'write_to_console' +} + +]] function Permissions_Groups._prototype:allow(actions) if type(actions) ~= 'table' then actions = {actions} @@ -167,9 +174,20 @@ function Permissions_Groups._prototype:allow(actions) return self end ---- Sets an action or actions to be disallowed for this group even with allow_all triggered, Do not use in runtime --- @tparam string|Array actions the action or actions that you want to disallow for this group --- @treturn Permissions_Groups._prototype returns self so function can be chained +--[[-- Sets an action or actions to be disallowed for this group even with allow_all triggered, Do not use in runtime +@tparam string|Array actions the action or actions that you want to disallow for this group +@treturn Permissions_Groups._prototype returns self so function can be chained + +@usage-- Disalow some actions +group:disallow{ + 'add_permission_group', + 'delete_permission_group', + 'import_permissions_string', + 'map_editor_action', + 'toggle_map_editor' +} + +]] function Permissions_Groups._prototype:disallow(actions) if type(actions) ~= 'table' then actions = {actions} @@ -180,23 +198,38 @@ function Permissions_Groups._prototype:disallow(actions) return self end ---- Sets the default state for any actions not given to be allowed, useful with :disallow --- @treturn Permissions_Groups._prototype returns self so function can be chained +--[[-- Sets the default state for any actions not given to be allowed, useful with :disallow +@treturn Permissions_Groups._prototype returns self so function can be chained + +@usage-- Allow all actions unless given by disallow +group:allow_all() + +]] function Permissions_Groups._prototype:allow_all() self.allow_all_actions = true return self end ---- Sets the default state for any action not given to be disallowed, useful with :allow --- @treturn Permissions_Groups._prototype returns self so function can be chained +--[[-- Sets the default state for any action not given to be disallowed, useful with :allow +@treturn Permissions_Groups._prototype returns self so function can be chained + +@usage-- Disallow all actions unless given by allow +group:disallow_all() + +]] function Permissions_Groups._prototype:disallow_all() self.allow_all_actions = false return self end ---- Returns if an input action is allowed for this group --- @tparam ?string|defines.input_action action the action that you want to test for --- @treturn boolean true if the group is allowed the action, false other wise +--[[-- Returns if an input action is allowed for this group +@tparam ?string|defines.input_action action the action that you want to test for +@treturn boolean true if the group is allowed the action, false other wise + +@usage-- Test if a group is allowed an action +local allowed = group:is_allowed('write_to_console') + +]] function Permissions_Groups._prototype:is_allowed(action) if type(action) == 'string' then action = defines.input_action[action] @@ -212,14 +245,13 @@ end -- Functions that control group players -- @section players ---- Returns the LuaPermissionGroup that was created with this group object, used internally --- @treturn LuaPermissionGroup the raw lua permission group -function Permissions_Groups._prototype:get_raw() - return game.permissions.get_group(self.name) -end +--[[-- Creates or updates the permission group with the configured actions, used internally +@treturn LuaPermissionGroup the permission group that was created ---- Creates or updates the permission group with the configured actions, used internally --- @treturn LuaPermissionGroup the permission group that was created +@usage-- Create the permission group so players can be added, used internally +group:create() + +]] function Permissions_Groups._prototype:create() local group = self:get_raw() if not group then @@ -231,9 +263,25 @@ function Permissions_Groups._prototype:create() return group end ---- Adds a player to this group --- @tparam LuaPlayer player LuaPlayer the player you want to add to this group can be name or index etc --- @treturn boolean true if the player was added successfully, false other wise +--[[-- Returns the LuaPermissionGroup that was created with this group object, used internally +@treturn LuaPermissionGroup the raw lua permission group + +@usage-- Get the factorio api permision group, used internally +local permission_group = group:get_raw() + +]] +function Permissions_Groups._prototype:get_raw() + return game.permissions.get_group(self.name) +end + +--[[-- Adds a player to this group +@tparam LuaPlayer player LuaPlayer the player you want to add to this group can be name or index etc +@treturn boolean true if the player was added successfully, false other wise + +@usage-- Add a player to this permission group +group:add_player(game.player) + +]] function Permissions_Groups._prototype:add_player(player) player = Game.get_player_from_any(player) local group = self:get_raw() @@ -242,9 +290,14 @@ function Permissions_Groups._prototype:add_player(player) return true end ---- Removes a player from this group --- @tparam LuaPlayer player LuaPlayer the player you want to remove from this group can be name or index etc --- @treturn boolean true if the player was removed successfully, false other wise +--[[-- Removes a player from this group +@tparam LuaPlayer player LuaPlayer the player you want to remove from this group can be name or index etc +@treturn boolean true if the player was removed successfully, false other wise + +@usage-- Remove a player from this permission group +group:remove_player(game.player) + +]] function Permissions_Groups._prototype:remove_player(player) player = Game.get_player_from_any(player) local group = self:get_raw() @@ -253,9 +306,17 @@ function Permissions_Groups._prototype:remove_player(player) return true end ---- Returns all player that are in this group with the option to filter to online/offline only --- @tparam[opt] boolean online if nil returns all players, if true online players only, if false returns online players only --- @treturn table a table of players that are in this group; filtered if online param is given +--[[-- Returns all player that are in this group with the option to filter to online/offline only +@tparam[opt] boolean online if nil returns all players, if true online players only, if false returns online players only +@treturn table a table of players that are in this group; filtered if online param is given + +@usage-- Get all players in this group +local online_players = group:get_players() + +@usage-- Get all online players in this group +local online_players = group:get_players(true) + +]] function Permissions_Groups._prototype:get_players(online) local players = {} local group = self:get_raw() @@ -273,9 +334,14 @@ function Permissions_Groups._prototype:get_players(online) return players end ---- Prints a message to every player in this group --- @tparam string message the message that you want to send to the players --- @treturn number the number of players that received the message +--[[-- Prints a message to every player in this group +@tparam string message the message that you want to send to the players +@treturn number the number of players that received the message + +@usage-- Print a message to all players in thie group +group:print('Hello, World!') + +]] function Permissions_Groups._prototype:print(message) local players = self:get_players(true) for _,player in pairs(players) do diff --git a/expcore/roles.lua b/expcore/roles.lua index 8c245ec8..5cd0610f 100644 --- a/expcore/roles.lua +++ b/expcore/roles.lua @@ -1,115 +1,111 @@ --[[-- Core Module - Roles - - Factorio role system to manage custom permissions. - @core Roles - @alias Roles +- Factorio role system to manage custom permissions. +@core Roles +@alias Roles - @usage ----- Using Role System (Frontend): - When a map first starts you will want to define on mass all the players you expect to join and the roles to give them: - Roles.override_player_roles{ - Cooldude2606 = {'Owner','Admin','Member'}, - NotCooldude2606 = {'Member'} - } +@usage--- Using Role System (assignment): +--When a map first starts you will want to define on mass all the players you expect to join and the roles to give them: +Roles.override_player_roles{ + Cooldude2606 = {'Owner','Admin','Member'}, + NotCooldude2606 = {'Member'} +} - Once the game is running you still want to be able to give role and remove them which is when you would use: - Roles.assign_player(player,'Admin',by_player_name) -- this will give the "Admin" role to the player - Roles.unassign_player(player,{'Admin','Moderator'},by_player_name) -- this will remove "Admin" and "Moderator" role in one go +--Once the game is running you still want to be able to give role and remove them which is when you would use: +Roles.assign_player(player,'Admin',by_player_name) -- this will give the "Admin" role to the player +Roles.unassign_player(player,{'Admin','Moderator'},by_player_name) -- this will remove "Admin" and "Moderator" role in one go - @usage ----- Using Role System (Backend): - To comparer two players you can comparer the index of they highest roles, can be used when you want to allow a "write" down type system: - Roles.get_player_highest_role(playerOne).index < Roles.get_player_highest_role(playerTwo).index -- remember that less means a higher role +@usage--- Using Role System (role testing): +--To comparer two players you can comparer the index of they highest roles, can be used when you want to allow a "write" down type system: +Roles.get_player_highest_role(playerOne).index < Roles.get_player_highest_role(playerTwo).index -- remember that less means a higher role - Listing all of a players roles can also be useful which is when you would want to use: - Roles.get_player_roles(player) -- the return is an array that can be looped over however this is not in particular order +--Listing all of a players roles can also be useful which is when you would want to use: +Roles.get_player_roles(player) -- the return is an array that can be looped over however this is not in particular order - Finally you may want to test if a player has a certain role, flag or action allowed which is when you would use: - Roles.player_has_role(player,'Admin') -- you can provide a role name if you only want a name based system - Roles.player_has_flag(player,'is_donator') -- your roles can be grouped together with flags such as is_donator - Roles.player_allowed(player,'game modifiers') -- or you can have an action based system where each action is something the player can do +--Finally you may want to test if a player has a certain role, flag or action allowed which is when you would use: +Roles.player_has_role(player,'Admin') -- you can provide a role name if you only want a name based system +Roles.player_has_flag(player,'is_donator') -- your roles can be grouped together with flags such as is_donator +Roles.player_allowed(player,'game modifiers') -- or you can have an action based system where each action is something the player can do - @usage ----- Example Flag Define: - Flags can be used to group multiple roles and actions under one catch all, for example if you want a piece of code to only - be active for your donators then you would add a "is_donator" flag to all your donator roles and then in the code test if - a player has that tag present: +@usage--- Example Flag Define: +--Flags can be used to group multiple roles and actions under one catch all, for example if you want a piece of code to only +--be active for your donators then you would add a "is_donator" flag to all your donator roles and then in the code test if +--a player has that tag present: - -- give you donators a speed boost when they join; these functions aren't required but can be useful - Roles.define_flag_trigger('is_donator',function(player,state) - if state then - player.character_running_speed_modifier = 1.5 - else - player.character_running_speed_modifier = 1 - end - end) - - -- then on all your donator roles you would add - Roles.new_role('Donator') - :set_flag('is_donator') - - -- and in your code you would test for - if Roles.player_has_flag(player,'is_donator') then - -- some donator only code +-- give you donators a speed boost when they join; these functions aren't required but can be useful +Roles.define_flag_trigger('is_donator',function(player,state) + if state then + player.character_running_speed_modifier = 1.5 + else + player.character_running_speed_modifier = 1 end +end) - @usage ----- Example Role Define: - You can't use a role system without any roles so first you must define your roles; each role has a minimum of a name with - the option for a shorthand: - Roles.new_role('Administrator','Admin') +-- then on all your donator roles you would add +Roles.new_role('Donator') +:set_flag('is_donator') - Next you will want to add any extras you want to have, such as a tag, colour, permission group or any custom flags: - Roles.new_role('Administrator','Admin') - :set_custom_tag('[Admin]') - :set_custom_color('red') -- this can be {r=0,g=0,b=0} or a predefined value - :set_permission_group('Staff') -- a second argument can be added if you have not used the custom permission group config - :set_flag('is_admin') +-- and in your code you would test for +if Roles.player_has_flag(player,'is_donator') then + -- some donator only code +end - You will then want to decide if you want to allow all actions, this should of course be used sparely: - Roles.new_role('Administrator','Admin') - ...extras... - :set_allow_all() +@usage--- Example Role Define: +--You can't use a role system without any roles so first you must define your roles; each role has a minimum of a name with +--the option for a shorthand: +Roles.new_role('Administrator','Admin') - If you don't do this want this as i would advise you do then you will want to define what the role can do; this comes with - an optional inheritance system if you like those sort of things in which case disallow may also be of some use to you: - Roles.new_role('Administrator','Admin') - ...extras... - :set_parent('Moderator') -- the admin can do anything that a moderator can do - :allow{ -- these actions can be anything just try to keep them without conflicts - 'command/kill', - 'gui/game settings' - } +--Next you will want to add any extras you want to have, such as a tag, colour, permission group or any custom flags: +Roles.new_role('Administrator','Admin') +:set_custom_tag('[Admin]') +:set_custom_color('red') -- this can be {r=0,g=0,b=0} or a predefined value +:set_permission_group('Staff') -- a second argument can be added if you have not used the custom permission group config +:set_flag('is_admin') - Here is what the finished admin role would look like: - Roles.new_role('Administrator','Admin') - :set_custom_tag('[Admin]') - :set_custom_color('red') - :set_permission_group('Staff') - :set_flag('is_admin') - :set_parent('Moderator') - :allow{ - 'command/kill', - 'gui/game settings' - } +--You will then want to decide if you want to allow all actions, this should of course be used sparely: +Roles.new_role('Administrator','Admin') +...extras... +:set_allow_all() - @usage ----- Example System Define: - Once all roles are defined these steps must be done to ensure the system is ready to use, this includes setting a default - role, assigning a root (all permission) role that the server/system will use and the linear order that the roles fall into: +--If you don't do this want this as i would advise you do then you will want to define what the role can do; this comes with +--an optional inheritance system if you like those sort of things in which case disallow may also be of some use to you: +Roles.new_role('Administrator','Admin') +...extras... +:set_parent('Moderator') -- the admin can do anything that a moderator can do +:allow{ -- these actions can be anything just try to keep them without conflicts + 'command/kill', + 'gui/game settings' +} - Roles.set_default('Guest') - Roles.set_root('System') +--Here is what the finished admin role would look like: +Roles.new_role('Administrator','Admin') +:set_custom_tag('[Admin]') +:set_custom_color('red') +:set_permission_group('Staff') +:set_flag('is_admin') +:set_parent('Moderator') +:allow{ + 'command/kill', + 'gui/game settings' +} - Roles.define_role_order{ - 'System', - 'Administrator', - 'Moderator', - 'Donator', - 'Guest' - } +@usage--- Example System Define: +--Once all roles are defined these steps must be done to ensure the system is ready to use, this includes setting a default +--role, assigning a root (all permission) role that the server/system will use and the linear order that the roles fall into: + +Roles.set_default('Guest') +Roles.set_root('System') + +Roles.define_role_order{ + 'System', + 'Administrator', + 'Moderator', + 'Donator', + 'Guest' +} + +--Just remember that in this example all these roles have not been defined; so make sure all your roles that are used are defined +--before hand; a config file on load is useful for this to ensure that its loaded before the first player even joins. - Just remember that in this example all these roles have not been defined; so make sure all your roles that are used are defined - before hand; a config file on load is useful for this to ensure that its loaded before the first player even joins. ]] local Game = require 'utils.game' --- @dep utils.game @@ -196,8 +192,13 @@ local function emit_player_roles_updated(player,type,roles,by_player_name,skip_g }) end ---- Returns a string which contains all roles in index order displaying all data for them --- @treturn string the debug output string +--[[-- Returns a string which contains all roles in index order displaying all data for them +@treturn string the debug output string + +@usage-- Print the debug string +game.player.print(Roles.debug()) + +]] function Roles.debug() local output = '' for index,role_name in pairs(Roles.config.order) do @@ -209,9 +210,14 @@ function Roles.debug() return output end ---- Prints a message to all players in the given roles, may send duplicate message however factorio blocks spam --- @tparam table roles table a of roles which to send the message to --- @tparam string message the message to send to the players +--[[-- Prints a message to all players in the given roles, may send duplicate message however factorio blocks spam +@tparam table roles table a of roles which to send the message to +@tparam string message the message to send to the players + +@usage-- Print a message to the given roles +Roles.print_to_roles({'Administrator','Moderator'}, 'Hello, World!') + +]] function Roles.print_to_roles(roles,message) for _,role in pairs(roles) do role = Roles.get_role_from_any(role) @@ -219,9 +225,14 @@ function Roles.print_to_roles(roles,message) end end ---- Prints a message to all players who have the given role or one which is higher (excluding default) --- @tparam string role the name of the role to send the message to --- @tparam string message the message to send to the players +--[[-- Prints a message to all players who have the given role or one which is higher (excluding default) +@tparam string role the name of the role to send the message to +@tparam string message the message to send to the players + +@usage-- Print a message to the roles above this role, includes the given role +Roles.print_to_roles_higher('Moderator', 'Hello, World!') + +]] function Roles.print_to_roles_higher(role,message) role = Roles.get_role_from_any(role) if not role then return end @@ -234,9 +245,14 @@ function Roles.print_to_roles_higher(role,message) Roles.print_to_roles(roles,message) end ---- Prints a message to all players who have the given role or one which is lower (excluding default) --- @tparam string role the name of the role to send the message to --- @tparam string message the message to send to the players +--[[-- Prints a message to all players who have the given role or one which is lower (excluding default) +@tparam string role the name of the role to send the message to +@tparam string message the message to send to the players + +@usage-- Print a message to the roles below this role, includes the given role +Roles.print_to_roles_higher('Moderator', 'Hello, World!') + +]] function Roles.print_to_roles_lower(role,message) role = Roles.get_role_from_any(role) if not role then return end @@ -249,25 +265,40 @@ function Roles.print_to_roles_lower(role,message) Roles.print_to_roles(roles,message) end ---- Get a role for the given name --- @tparam string name the name of the role to get --- @treturn Roles._prototype the role with that name or nil +--[[-- Get a role for the given name +@tparam string name the name of the role to get +@treturn Roles._prototype the role with that name or nil + +@usage-- Get a role by its name +local role = Roles.get_role_by_name('Moderator') + +]] function Roles.get_role_by_name(name) return Roles.config.roles[name] end ---- Get a role with the given order index --- @tparam number index the place in the order list of the role to get --- @treturn Roles._prototype the role with that index in the order list or nil +--[[-- Get a role with the given order index +@tparam number index the place in the order list of the role to get +@treturn Roles._prototype the role with that index in the order list or nil + +@usage-- Get a role by its index in the order list +local role = Roles.get_role_by_name(2) + +]] function Roles.get_role_by_order(index) local name = Roles.config.order[index] return Roles.config.roles[name] end ---- Gets a role from a name,index or role object (where it is just returned) --- nb: this function is used for the input for most outward facing functions --- @tparam ?number|string|table any the value used to find the role --- @treturn Roles._prototype the role that was found or nil see above +--[[-- Gets a role from a name,index or role object (where it is just returned) +nb: this function is used for the input for most outward facing functions +@tparam ?number|string|table any the value used to find the role +@treturn Roles._prototype the role that was found or nil see above + +@usage-- Get a role by its name or order +local role = Roles.get_role_from_any('Moderator') + +]] function Roles.get_role_from_any(any) local t_any = type(any) if t_any == 'number' or tonumber(any) then @@ -280,9 +311,14 @@ function Roles.get_role_from_any(any) end end ---- Gets all the roles of the given player, this will always contain the default role --- @tparam LuaPlayer player the player to get the roles of --- @treturn table a table where the values are the roles which the player has +--[[-- Gets all the roles of the given player, this will always contain the default role +@tparam LuaPlayer player the player to get the roles of +@treturn table a table where the values are the roles which the player has + +@usage-- Get the roles that a player has +local roles = Roles.get_player_roles(game.player) + +]] function Roles.get_player_roles(player) player = Game.get_player_from_any(player) if not player then return {Roles.config.roles[Roles.config.internal.root]} end @@ -295,9 +331,14 @@ function Roles.get_player_roles(player) return rtn end ---- Gets the highest role which the player has, can be used to compeer one player to another --- @tparam LuaPlayer player the player to get the highest role of --- @treturn the role with the highest order index which this player has +--[[-- Gets the highest role which the player has, can be used to compeer one player to another +@tparam LuaPlayer player the player to get the highest role of +@treturn the role with the highest order index which this player has + +@usage-- Get the highest role that a player has +local role = Roles.get_player_highest_role(game.player) + +]] function Roles.get_player_highest_role(player) local roles = Roles.get_player_roles(player) if not roles then return end @@ -314,12 +355,20 @@ end -- Functions for changing player's roles -- @section assinment ---- Gives a player the given role(s) with an option to pass a by player name used in the log --- @tparam LuaPlayer player the player that will be assigned the roles --- @tparam table roles table a of roles that the player will be given, can be one role and can be role names --- @tparam[opt=] string by_player_name the name of the player that will be shown in the log --- @tparam[opt=false] boolean skip_checks when true there will be no checks are done for if the player is valid --- @tparam[opt=false] boolean silent when true there will be no game message printed +--[[-- Gives a player the given role(s) with an option to pass a by player name used in the log +@tparam LuaPlayer player the player that will be assigned the roles +@tparam table roles table a of roles that the player will be given, can be one role and can be role names +@tparam[opt=] string by_player_name the name of the player that will be shown in the log +@tparam[opt=false] boolean skip_checks when true there will be no checks are done for if the player is valid +@tparam[opt=false] boolean silent when true there will be no game message printed + +@usage-- Assign a player to the Moderator role +Roles.assign_player(game.player, 'Moderator') + +@usage-- Assign a player to the Moderator role, even if the player has never been on the map +Roles.assign_player('Cooldude2606', 'Moderator', nil, true) + +]] function Roles.assign_player(player,roles,by_player_name,skip_checks,silent) local valid_player = Game.get_player_from_any(player) if not skip_checks and not valid_player then return end @@ -337,12 +386,20 @@ function Roles.assign_player(player,roles,by_player_name,skip_checks,silent) end end ---- Removes a player from the given role(s) with an option to pass a by player name used in the log --- @tparam LuaPlayer player the player that will have the roles removed --- @tparam table roles table a of roles to be removed from the player, can be one role and can be role names --- @tparam[opt=] string by_player_name the name of the player that will be shown in the logs --- @tparam[opt=false] boolean skip_checks when true there will be no checks are done for if the player is valid --- @tparam[opt=false] boolean silent when true there will be no game message printed +--[[-- Removes a player from the given role(s) with an option to pass a by player name used in the log +@tparam LuaPlayer player the player that will have the roles removed +@tparam table roles table a of roles to be removed from the player, can be one role and can be role names +@tparam[opt=] string by_player_name the name of the player that will be shown in the logs +@tparam[opt=false] boolean skip_checks when true there will be no checks are done for if the player is valid +@tparam[opt=false] boolean silent when true there will be no game message printed + +@usage-- Unassign a player from the Moderator role +Roles.unassign_player(game.player, 'Moderator') + +@usage-- Unassign a player from the Moderator role, even if the player has never been on the map +Roles.unassign_player('Cooldude2606', 'Moderator', nil, true) + +]] function Roles.unassign_player(player,roles,by_player_name,skip_checks,silent) local valid_player = Game.get_player_from_any(player) if not skip_checks and not valid_player then return end @@ -361,20 +418,41 @@ function Roles.unassign_player(player,roles,by_player_name,skip_checks,silent) end end ---- Overrides all player roles with the given table of roles, useful to mass set roles on game start --- @tparam table roles table a which is indexed by case sensitive player names and has the value of a table of role names -function Roles.override_player_roles(roles) - Roles.config.players = roles +--[[-- Overrides all player roles with the given table of roles, useful to mass set roles on game start +@tparam[opt] string player_name the player to set the roles for, if not given all roles are overriden +@tparam table roles table a which is indexed by case sensitive player names and has the value of a table of role names + +@usage-- Override the roles of a single player, other users are not effected +Roles.override_player_roles('Cooldude2606', {'Moderator'}) + +@usage-- Override all existing roles, effects all users not just ones listed +Roles.override_player_roles{ + ['Cooldude2606'] = {'Administrator','Moderator'}, + ['arty714'] = {'Administrator','Moderator'}, +} + +]] +function Roles.override_player_roles(player_name,roles) + if not roles then + Roles.config.players = player_name + else + Roles.config.players[player_name] = roles + end end --- Checks. -- Functions for checking player's roles -- @section checks ---- A test for weather a player has the given role --- @tparam LuaPlayer player the player to test the roles of --- @tparam ?string|number|table search_role a pointer to the role that is being searched for --- @treturn boolean true if the player has the role, false otherwise, nil for errors +--[[-- A test for weather a player has the given role +@tparam LuaPlayer player the player to test the roles of +@tparam ?string|number|table search_role a pointer to the role that is being searched for +@treturn boolean true if the player has the role, false otherwise, nil for errors + +@usage-- Test if a player has a role +local has_role = Roles.player_has_role(game.player, 'Moderator') + +]] function Roles.player_has_role(player,search_role) local roles = Roles.get_player_roles(player) if not roles then return end @@ -386,10 +464,15 @@ function Roles.player_has_role(player,search_role) return false end ---- A test for weather a player has the given flag true for at least one of they roles --- @tparam LuaPlayer player the player to test the roles of --- @tparam string flag_name the name of the flag that is being looked for --- @treturn boolean true if the player has at least one role which has the flag set to true, false otherwise, nil for errors +--[[-- A test for weather a player has the given flag true for at least one of they roles +@tparam LuaPlayer player the player to test the roles of +@tparam string flag_name the name of the flag that is being looked for +@treturn boolean true if the player has at least one role which has the flag set to true, false otherwise, nil for errors + +@usage-- Test if a player has a role +local has_flag = Roles.player_has_flag(game.player, 'is_donator') + +]] function Roles.player_has_flag(player,flag_name) local roles = Roles.get_player_roles(player) if not roles then return end @@ -401,10 +484,15 @@ function Roles.player_has_flag(player,flag_name) return false end ---- A test for weather a player has at least one role which is allowed the given action --- @tparam LuaPlayer player the player to test the roles of --- @tparam string action the name of the action that is being tested for --- @treturn boolean true if the player has at least one role which is allowed this action, false otherwise, nil for errors +--[[-- A test for weather a player has at least one role which is allowed the given action +@tparam LuaPlayer player the player to test the roles of +@tparam string action the name of the action that is being tested for +@treturn boolean true if the player has at least one role which is allowed this action, false otherwise, nil for errors + +@usage-- Test if a player has a role +local has_flag = Roles.player_has_flag(game.player, 'is_donator') + +]] function Roles.player_allowed(player,action) local roles = Roles.get_player_roles(player) if not roles then return end @@ -420,9 +508,20 @@ end -- Functions which are used to define roles -- @section checks ---- Used to set the role order, higher in the list is better, must be called at least once in config +--[[-- Used to set the role order, higher in the list is better, must be called at least once in config -- nb: function also re links parents due to expected position in the config file --- @tparam table order table a which is keyed only by numbers (start 1) and values are roles in order with highest first +@tparam table order table a which is keyed only by numbers (start 1) and values are roles in order with highest first + +@usage-- Define which roles are higher than others +Roles.define_role_order{ + 'System', + 'Administrator', + 'Moderator', + 'Donator', + 'Guest' +} + +]] function Roles.define_role_order(order) -- Clears and then rebuilds the order table _C.error_if_runtime() @@ -457,26 +556,41 @@ function Roles.define_role_order(order) end end ---- Defines a new trigger for when a tag is added or removed from a player --- @tparam string name the name of the flag which the roles will have --- @tparam function callback the function that is called when roles are assigned --- flag param - player - the player that has had they roles changed --- flag param - state - the state of the flag, aka if the flag is present +--[[-- Defines a new trigger for when a tag is added or removed from a player +@tparam string name the name of the flag which the roles will have +@tparam function callback the function that is called when roles are assigned + +@usage-- Defineing a flag trigger +Roles.define_flag_trigger('is_donator', function(player, state) + player.character_running_speed_modifier = state and 1.5 or 1 +end) + +]] function Roles.define_flag_trigger(name,callback) _C.error_if_runtime() Roles.config.flags[name] = Async.register(callback) end ---- Sets the default role which every player will have, this needs to be called at least once --- @tparam string name the name of the default role +--[[-- Sets the default role which every player will have, this needs to be called at least once +@tparam string name the name of the default role + +@usage-- Setting the default role +Roles.set_default('Guest') + +]] function Roles.set_default(name) local role = Roles.config.roles[name] if not role then return end Roles.config.internal.default = name end ---- Sets the root role which will always have all permissions, any server actions act from this role --- @tparam string name the name of the root role +--[[-- Sets the root role which will always have all permissions, any server actions act from this role +@tparam string name the name of the root role + +@usage-- Setting the root role +Roles.set_root('System') + +]] function Roles.set_root(name) local role = Roles.config.roles[name] if not role then return end @@ -484,10 +598,15 @@ function Roles.set_root(name) Roles.config.internal.root = name end ---- Defines a new role and returns the prototype to allow configuration --- @tparam string name the name of the new role, must be unique --- @tparam[opt=name] string short_hand the shortened version of the name --- @treturn Roles._prototype the start of the config chain for this role +--[[-- Defines a new role and returns the prototype to allow configuration +@tparam string name the name of the new role, must be unique +@tparam[opt=name] string short_hand the shortened version of the name +@treturn Roles._prototype the start of the config chain for this role + +@usage-- Defineing a new role +local role = Roles.new_role('Moderator', 'Mod') + +]] function Roles.new_role(name,short_hand) _C.error_if_runtime() if Roles.config.roles[name] then return error('Role name is non unique') end @@ -506,18 +625,31 @@ end -- Functions for using the role action system -- @section actions ---- Sets the default allow state of the role, true will allow all actions --- @tparam[opt=true] boolean state true will allow all actions --- @treturn Roles._prototype allows chaining +--[[-- Sets the default allow state of the role, true will allow all actions +@tparam[opt=true] boolean state true will allow all actions +@treturn Roles._prototype allows chaining + +@usage-- Allow all actions for this role, useful for root like roles +role:set_allow_all() + +]] function Roles._prototype:set_allow_all(state) if state == nil then state = true end self.allow_all_actions = not not state -- not not forces a boolean value return self end ---- Sets the allow actions for this role, actions in this list will be allowed for this role --- @tparam table actions indexed with numbers and is an array of action names, order has no effect --- @treturn Roles._prototype allows chaining +--[[-- Sets the allow actions for this role, actions in this list will be allowed for this role +@tparam table actions indexed with numbers and is an array of action names, order has no effect +@treturn Roles._prototype allows chaining + +@usage-- Allow some actions for a role +role:allow{ + 'command/kill', + 'gui/game settings' +} + +]] function Roles._prototype:allow(actions) if type(actions) ~= 'table' then actions = {actions} @@ -528,9 +660,17 @@ function Roles._prototype:allow(actions) return self end ---- Sets the disallow actions for this role, will prevent actions from being allowed regardless of inheritance --- @tparam table actions indexed with numbers and is an array of action names, order has no effect --- @treturn Roles._prototype allows chaining +--[[-- Sets the disallow actions for this role, will prevent actions from being allowed regardless of inheritance +@tparam table actions indexed with numbers and is an array of action names, order has no effect +@treturn Roles._prototype allows chaining + +@usage-- Disalow an action for a role, useful if inherit an action from a parent +role:disallow{ + 'command/kill', + 'gui/game settings' +} + +]] function Roles._prototype:disallow(actions) if type(actions) ~= 'table' then actions = {actions} @@ -541,9 +681,14 @@ function Roles._prototype:disallow(actions) return self end ---- Test for if a role is allowed the given action, mostly internal see Roles.player_allowed --- @tparam string action the name of the action to test if it is allowed --- @treturn boolean true if action is allowed, false otherwise +--[[-- Test for if a role is allowed the given action, mostly internal see Roles.player_allowed +@tparam string action the name of the action to test if it is allowed +@treturn boolean true if action is allowed, false otherwise + +@usage-- Test if a role is allowed an action +local allowed = role:is_allowed('command/kill') + +]] function Roles._prototype:is_allowed(action) local is_root = Roles.config.internal.root.name == self.name return self.allowed_actions[action] or self.allow_all_actions or is_root @@ -553,26 +698,41 @@ end -- Functions for using the role flag system -- @section flags ---- Sets the state of a flag for a role, flags can be used to apply effects to players --- @tparam string name the name of the flag to set the value of --- @tparam[opt=true] boolean value the state to set the flag to --- @treturn Roles._prototype allows chaining +--[[-- Sets the state of a flag for a role, flags can be used to apply effects to players +@tparam string name the name of the flag to set the value of +@tparam[opt=true] boolean value the state to set the flag to +@treturn Roles._prototype allows chaining + +@usage-- Set a flag for a role +role:set_flag('is_admin') + +]] function Roles._prototype:set_flag(name,value) if value == nil then value = true end self.flags[name] = not not value -- not not forces a boolean value return self end ---- Clears all flags from this role, individual flags can be removed with set_flag(name,false) --- @treturn Roles._prototype allows chaining +--[[-- Clears all flags from this role, individual flags can be removed with set_flag(name,false) +@treturn Roles._prototype allows chaining + +@usage-- Remove all flags from a role +role:clear_flags() + +]] function Roles._prototype:clear_flags() self.flags = {} return self end ---- A test for if the role has a flag set --- @tparam string name the name of the flag to test for --- @treturn boolean true if the flag is set, false otherwise +--[[-- A test for if the role has a flag set +@tparam string name the name of the flag to test for +@treturn boolean true if the flag is set, false otherwise + +@usage-- Test if a role has a flag +local has_flag = role:has_flag('is_admin') + +]] function Roles._prototype:has_flag(name) return self.flags[name] or false end @@ -581,17 +741,27 @@ end -- Functions for chaning other proerties -- @section properties ---- Sets a custom player tag for the role, can be accessed by other code --- @tparam string tag the value that the tag will be --- @treturn Roles._prototype allows chaining +--[[-- Sets a custom player tag for the role, can be accessed by other code +@tparam string tag the value that the tag will be +@treturn Roles._prototype allows chaining + +@usage-- Set a custom tag for this role, other code is required to set the tag +role:set_custom_tag('Mod') + +]] function Roles._prototype:set_custom_tag(tag) self.custom_tag = tag return self end ---- Sets a custom colour for the role, can be accessed by other code --- @tparam table color ?string|table can either be and rgb colour or the name of a colour defined in the presets --- @treturn Roles._prototype allows chaining +--[[-- Sets a custom colour for the role, can be accessed by other code +@tparam table color ?string|table can either be and rgb colour or the name of a colour defined in the presets +@treturn Roles._prototype allows chaining + +@usage-- Set a custom colour for this role, other code is required to use this value +role:set_custom_color{ r=255, g=100, b=100} + +]] function Roles._prototype:set_custom_color(color) if type(color) ~= 'table' then color = Colours[color] @@ -600,10 +770,15 @@ function Roles._prototype:set_custom_color(color) return self end ---- Sets the permission group for this role, players will be moved to the group of they highest role --- @tparam string name the name of the permission group to have players moved to --- @tparam[opt=false] boolean use_factorio_api when true the custom permission group module is ignored --- @treturn Roles._prototype allows chaining +--[[-- Sets the permission group for this role, players will be moved to the group of they highest role +@tparam string name the name of the permission group to have players moved to +@tparam[opt=false] boolean use_factorio_api when true the custom permission group module is ignored +@treturn Roles._prototype allows chaining + +@usage-- Set the permission group for this role, see permission_groups.lua +role:set_permission_group('Admin') + +]] function Roles._prototype:set_permission_group(name,use_factorio_api) _C.error_if_runtime() if use_factorio_api then @@ -616,10 +791,15 @@ function Roles._prototype:set_permission_group(name,use_factorio_api) return self end ---- Sets the parent for a role, any action not in allow or disallow will be looked for in its parents --- nb: this is a recursive action, and changing the allows and disallows will effect all children roles --- @tparam string role the name of the role that will be the parent; has imminent effect if role is already defined --- @treturn Roles._prototype allows chaining +--[[-- Sets the parent for a role, any action not in allow or disallow will be looked for in its parents +nb: this is a recursive action, and changing the allows and disallows will effect all children roles +@tparam string role the name of the role that will be the parent; has imminent effect if role is already defined +@treturn Roles._prototype allows chaining + +@usage-- Set the parent for this role to inherit all actions allowed +role:set_parent('Guest') + +]] function Roles._prototype:set_parent(role) _C.error_if_runtime() self.parent = role @@ -629,19 +809,31 @@ function Roles._prototype:set_parent(role) return self end ---- Sets an auto promote condition that is checked every 5 seconds, if true is returned then the player will receive the role --- nb: this is one way, failing false after already gaining the role will not revoke the role --- @tparam function callback receives only one param which is player to promote, return true to promote the player --- @treturn Roles._prototype allows chaining -function Roles._prototype:set_auto_promote_condition(callback) +--[[-- Sets an auto assign condition that is checked every 60 seconds, if true is returned then the player will receive the role +nb: this is one way, failing false after already gaining the role will not revoke the role +@tparam function callback receives only one param which is player to promote, return true to promote the player +@treturn Roles._prototype allows chaining + +@usage-- Give this role to a user if there are admin, ran every 60 seconds +role:set_auto_assign_condition(function(player) + return player.admin +end) + +]] +function Roles._prototype:set_auto_assign_condition(callback) _C.error_if_runetime_closure(callback) self.auto_promote_condition = callback return self end ---- Sets the role to not allow players to have auto promote effect them, useful to keep people locked to a punishment --- @tparam[opt=true] boolean state when true the players with this role will not be auto promoted --- @treturn Roles._prototype allows chaining +--[[-- Sets the role to not allow players to have auto assign effect them, useful to keep people locked to a role +@tparam[opt=true] boolean state when true the players with this role will not be auto assigned to other roles +@treturn Roles._prototype allows chaining + +@usage-- Make a role stop players from being auto assigned to other roles +role:set_block_auto_promote() + +]] function Roles._prototype:set_block_auto_promote(state) if state == nil then state = true end self.block_auto_promote = not not state -- forces a boolean value @@ -652,11 +844,16 @@ end -- Functions that control players in a role -- @section players ---- Adds a player to this role, players can have more than one role at a time, used internally see Roles.assign --- @tparam LuaPlayer player the player that will be given this role --- @tparam boolean skip_check when true player will be taken as the player name (use when player has not yet joined) --- @tparam boolean skip_event when true the event emit will be skipped, this is used internally with Roles.assign --- @treturn boolean true if the player was added successfully +--[[-- Adds a player to this role, players can have more than one role at a time, used internally see Roles.assign +@tparam LuaPlayer player the player that will be given this role +@tparam boolean skip_check when true player will be taken as the player name (use when player has not yet joined) +@tparam boolean skip_event when true the event emit will be skipped, this is used internally with Roles.assign +@treturn boolean true if the player was added successfully + +@usage-- Assign a player to this role +role:add_player(game.player) + +]] function Roles._prototype:add_player(player,skip_check,skip_event) player = Game.get_player_from_any(player) -- Default role cant have players added or removed @@ -686,11 +883,16 @@ function Roles._prototype:add_player(player,skip_check,skip_event) return true end ---- Removes a player from this role, players can have more than one role at a time, used internally see Roles.unassign --- @tparam LuaPlayer player the player that will lose this role --- @tparam boolean skip_check when true player will be taken as the player name (use when player has not yet joined) --- @tparam boolean skip_event when true the event emit will be skipped, this is used internally with Roles.unassign --- @treturn boolean true if the player was removed successfully +--[[-- Removes a player from this role, players can have more than one role at a time, used internally see Roles.unassign +@tparam LuaPlayer player the player that will lose this role +@tparam boolean skip_check when true player will be taken as the player name (use when player has not yet joined) +@tparam boolean skip_event when true the event emit will be skipped, this is used internally with Roles.unassign +@treturn boolean true if the player was removed successfully + +@usage-- Unassign a player from this role +role:remove_player(game.player) + +]] function Roles._prototype:remove_player(player,skip_check,skip_event) player = Game.get_player_from_any(player) -- Default role cant have players added or removed @@ -725,9 +927,17 @@ function Roles._prototype:remove_player(player,skip_check,skip_event) return rtn end ---- Returns an array of all the players who have this role, can be filtered by online status --- @tparam[opt=nil] boolean online when given will filter by this online state, nil will return all players --- @treturn table all the players who have this role, indexed order is meaningless +--[[-- Returns an array of all the players who have this role, can be filtered by online status +@tparam[opt=nil] boolean online when given will filter by this online state, nil will return all players +@treturn table all the players who have this role, indexed order is meaningless + +@usage-- Get all the players with this role +local players = role:get_players() + +@usage-- Get all online players with this role +local players = role:get_players(true) + +]] function Roles._prototype:get_players(online) local players = {} -- Gets all players that have this role @@ -756,9 +966,14 @@ function Roles._prototype:get_players(online) end end ---- Will print a message to all players with this role --- @tparam string message the message that will be printed to the players --- @treturn number the number of players who received the message +--[[-- Will print a message to all players with this role +@tparam string message the message that will be printed to the players +@treturn number the number of players who received the message + +@usage-- Print a message to all players with this role +role:print('Hello, World!') + +]] function Roles._prototype:print(message) local players = self:get_players(true) for _,player in pairs(players) do diff --git a/modules/addons/greetings.lua b/modules/addons/greetings.lua index 068e33e7..4541f42e 100644 --- a/modules/addons/greetings.lua +++ b/modules/addons/greetings.lua @@ -1,4 +1,5 @@ ---greets players on join +--- Greets players on join +-- @addon greetings local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.event diff --git a/modules/commands/admin-chat.lua b/modules/commands/admin-chat.lua index faf239f7..19aae6cb 100644 --- a/modules/commands/admin-chat.lua +++ b/modules/commands/admin-chat.lua @@ -13,7 +13,7 @@ require 'config.expcore.command_general_parse' Commands.new_command('admin-chat','Sends a message in chat that only admins can see.') :add_param('message',false) :enable_auto_concat() -:set_flag('admin_only',true) +:set_flag('admin_only') :add_alias('ac') :register(function(player,message,raw) local player_name_colour = format_chat_player_name(player) diff --git a/modules/commands/cheat-mode.lua b/modules/commands/cheat-mode.lua index f3f525df..c2eb462a 100644 --- a/modules/commands/cheat-mode.lua +++ b/modules/commands/cheat-mode.lua @@ -14,7 +14,7 @@ Commands.new_command('toggle-cheat-mode','Toggles cheat mode for your player, or :set_defaults{player=function(player) return player -- default is the user using the command end} -:set_flag('admin_only',true) +:set_flag('admin_only') :register(function(player,action_player,raw) action_player.cheat_mode = not action_player.cheat_mode end) \ No newline at end of file diff --git a/modules/commands/interface.lua b/modules/commands/interface.lua index 67dbd035..5f105d45 100644 --- a/modules/commands/interface.lua +++ b/modules/commands/interface.lua @@ -63,7 +63,7 @@ end Commands.new_command('interface','Sends an innovation to be ran and returns the result.') :add_param('innovation',false) :enable_auto_concat() -:set_flag('admin_only',true) +:set_flag('admin_only') :register(function(player,innovation,raw) if not innovation:find('%s') and not innovation:find('return') then -- if there are no spaces and return is not present then return is appended to the start diff --git a/modules/commands/roles.lua b/modules/commands/roles.lua index af36302a..1005b322 100644 --- a/modules/commands/roles.lua +++ b/modules/commands/roles.lua @@ -15,7 +15,7 @@ local format_chat_player_name, format_chat_colour_localized = _C.format_chat_pla Commands.new_command('assign-role','Assigns a role to a player') :add_param('player',false,'player-role') :add_param('role',false,'role') -:set_flag('admin-only',true) +:set_flag('admin-only') :add_alias('rpromote','assign','role','add-role') :register(function(player,action_player,role,raw) local player_highest = Roles.get_player_highest_role(player) @@ -33,7 +33,7 @@ end) Commands.new_command('unassign-role','Unassigns a role from a player') :add_param('player',false,'player-role') :add_param('role',false,'role') -:set_flag('admin-only',true) +:set_flag('admin-only') :add_alias('rdemote','unassign','rerole','remove-role') :register(function(player,action_player,role,raw) local player_highest = Roles.get_player_highest_role(player) diff --git a/modules/commands/teleport.lua b/modules/commands/teleport.lua index f5e88906..5e8ea3b4 100644 --- a/modules/commands/teleport.lua +++ b/modules/commands/teleport.lua @@ -23,7 +23,7 @@ Commands.new_command('teleport','Teleports a player to another player.') :add_param('from_player',false,'player-alive') :add_param('to_player',false,'player-online') :add_alias('tp') -:set_flag('admin_only',true) +:set_flag('admin_only') :register(function(player,from_player,to_player,raw) if from_player.index == to_player.index then -- return if attempting to teleport to self @@ -40,7 +40,7 @@ end) -- @tparam LuaPlayer player the player that will be teleported, must be alive Commands.new_command('bring','Teleports a player to you.') :add_param('player',false,'player-alive') -:set_flag('admin_only',true) +:set_flag('admin_only') :register(function(player,from_player,raw) if from_player.index == player.index then -- return if attempting to teleport to self @@ -58,7 +58,7 @@ end) Commands.new_command('goto','Teleports you to a player.') :add_param('player',false,'player-online') :add_alias('tp-me','tpme') -:set_flag('admin_only',true) +:set_flag('admin_only') :register(function(player,to_player,raw) if to_player.index == player.index then -- return if attempting to teleport to self diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index 40656e79..2081cb9e 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -38,7 +38,7 @@ local function check_player_permissions(player,action) end --- Button to toggle the auto launch on a rocket silo --- @elemeent toggle_launch +-- @element toggle_launch local toggle_launch = Gui.element{ type = 'sprite-button', From 0a8e5b55646493f94fbaf0d60467953b94753918 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 3 Apr 2020 13:27:41 +0100 Subject: [PATCH 67/81] Fixed warnings not working --- modules/control/warnings.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/control/warnings.lua b/modules/control/warnings.lua index ebd3612d..2e6d057b 100644 --- a/modules/control/warnings.lua +++ b/modules/control/warnings.lua @@ -113,8 +113,8 @@ function Warnings.add_warning(player,by_player_name,reason) local warning_count = #warnings - script.raise_event(Warnings.on_warning_added,{ - name = Warnings.on_warning_added, + script.raise_event(Warnings.events.on_warning_added,{ + name = Warnings.events.on_warning_added, tick = game.tick, player_index = player.index, warning_count = warning_count, @@ -146,8 +146,8 @@ end -- @tparam string removed_by_name the name of the player who is doing the action -- @tparam number warning_count the number of warnings that the player how has local function warning_removed_event(player,warning_by_name,removed_by_name,warning_count) - script.raise_event(Warnings.on_warning_removed,{ - name = Warnings.on_warning_removed, + script.raise_event(Warnings.events.on_warning_removed,{ + name = Warnings.events.on_warning_removed, tick = game.tick, player_index = player.index, warning_count = warning_count, @@ -234,8 +234,8 @@ function Warnings.add_script_warning(player,reason) local warning_count = #warnings - script.raise_event(Warnings.on_script_warning_added,{ - name = Warnings.on_script_warning_added, + script.raise_event(Warnings.events.on_script_warning_added,{ + name = Warnings.events.on_script_warning_added, tick = game.tick, player_index = player.index, warning_count = warning_count, @@ -253,8 +253,8 @@ end -- @tparam LuaPlayer player the player who is having a script warning removed -- @tparam number warning_count the number of warning that the player has local function script_warning_removed_event(player,warning_count) - script.raise_event(Warnings.on_script_warning_removed,{ - name = Warnings.on_script_warning_removed, + script.raise_event(Warnings.events.on_script_warning_removed,{ + name = Warnings.events.on_script_warning_removed, tick = game.tick, player_index = player.index, warning_count = warning_count From b5d14f9bddfd45ff63f7b99943a5cd32d9d63d38 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 4 Apr 2020 20:37:17 +0100 Subject: [PATCH 68/81] Fixed Issues with jail --- config/expcore/permission_groups.lua | 2 +- expcore/roles.lua | 2 +- locale/en/addons.cfg | 2 +- modules/addons/chat-reply.lua | 2 +- modules/commands/jail.lua | 6 ++++-- modules/control/jail.lua | 20 ++++++++++---------- 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/config/expcore/permission_groups.lua b/config/expcore/permission_groups.lua index 74fc894b..812584b7 100644 --- a/config/expcore/permission_groups.lua +++ b/config/expcore/permission_groups.lua @@ -13,7 +13,7 @@ Permission_Groups.new_group('Admin') :disallow{ 'add_permission_group', -- admin 'delete_permission_group', - --'edit_permission_group', -- removed for admin till role script added + 'edit_permission_group', 'import_permissions_string', 'map_editor_action', 'toggle_map_editor', diff --git a/expcore/roles.lua b/expcore/roles.lua index 5cd0610f..65485c00 100644 --- a/expcore/roles.lua +++ b/expcore/roles.lua @@ -178,7 +178,7 @@ local function emit_player_roles_updated(player,type,roles,by_player_name,skip_g player.play_sound{path='utility/game_lost'} end script.raise_event(event,{ - name=Roles.player_roles_updated, + name=event, tick=game.tick, player_index=player.index, by_player_index=by_player_index, diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index 86081d87..9281e461 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -26,7 +26,7 @@ status=Want to check if out servers are down? Visit: https://status.explosivegam github=Want to help improve our server with some extra features? Help us at: https://github.com/explosivegaming/scenario patreon=Consider supporting our server at: https://www.patreon.com/ExpGaming custom-commands=We use custom commands, such as /tag and /me, use /chelp for more info. -read-readme=Make sure you have read the Readme (It can be found through the question mark on the top left) +read-readme=Make sure you have read the information gui (It can be found through the info mark on the top left) softmod=We run a softmod on our servers. A softmod is a custom scenario that runs on this server, an example is the player list. redmew=We don't talk about redmew here; they beat us to 1000 members ;-; lhd=All trains must be LHD! This is a long standing rule on our servers, please respect this. diff --git a/modules/addons/chat-reply.lua b/modules/addons/chat-reply.lua index 4a17d70c..a4685ef3 100644 --- a/modules/addons/chat-reply.lua +++ b/modules/addons/chat-reply.lua @@ -28,7 +28,7 @@ Event.add(defines.events.on_console_chat,function(event) else player.print{'chat-bot.disallow'} end - else + elseif not allowed then player.print{'chat-bot.reply',reply} end end diff --git a/modules/commands/jail.lua b/modules/commands/jail.lua index cea441d8..59e12500 100644 --- a/modules/commands/jail.lua +++ b/modules/commands/jail.lua @@ -20,7 +20,8 @@ Commands.new_command('jail','Puts a player into jail and removes all other roles reason = reason or 'Non Given.' local action_player_name_color = format_chat_player_name(action_player) local by_player_name_color = format_chat_player_name(player) - if Jail.jail_player(action_player,player.name,reason) then + local player_name = player and player.name or '' + if Jail.jail_player(action_player, player_name, reason) then game.print{'expcom-jail.give',action_player_name_color,by_player_name_color,reason} else return Commands.error{'expcom-jail.already-jailed',action_player_name_color} @@ -37,7 +38,8 @@ Commands.new_command('unjail','Removes a player from jail.') :register(function(player,action_player,raw) local action_player_name_color = format_chat_player_name(action_player) local by_player_name_color = format_chat_player_name(player) - if Jail.unjail_player(action_player,player.name) then + local player_name = player and player.name or '' + if Jail.unjail_player(action_player, player_name) then game.print{'expcom-jail.remove',action_player_name_color,by_player_name_color} else return Commands.error{'expcom-jail.not-jailed',action_player_name_color} diff --git a/modules/control/jail.lua b/modules/control/jail.lua index e0cfe837..a188d984 100644 --- a/modules/control/jail.lua +++ b/modules/control/jail.lua @@ -114,10 +114,10 @@ function Jail.jail_player(player,by_player_name,reason) local roles = get_roles(player) old_roles[player.name] = roles - assign_roles(player,'Jail',by_player_name,true) - unassign_roles(player,old_roles,by_player_name,true) + assign_roles(player, 'Jail', by_player_name, nil, true) + unassign_roles(player, roles, by_player_name, nil, true) - event_emit(Jail.events.on_player_jailed,player,by_player_name,reason) + event_emit(Jail.events.on_player_jailed, player, by_player_name, reason) return true end @@ -134,10 +134,10 @@ function Jail.unjail_player(player,by_player_name) if not has_role(player,'Jail') then return end local roles = old_roles[player.name] or {} - assign_roles(player,roles,by_player_name,true) - unassign_roles(player,'Jail',by_player_name,true) + assign_roles(player, roles, by_player_name, nil, true) + unassign_roles(player, 'Jail', by_player_name, nil, true) - event_emit(Jail.events.on_player_unjailed,player,by_player_name) + event_emit(Jail.events.on_player_unjailed, player, by_player_name) return true end @@ -174,8 +174,8 @@ function Jail.temp_ban_player(player,by_player_name,reason) local roles = get_roles(player) old_roles[player.name] = roles - assign_roles(player,'Jail',by_player_name,true) - unassign_roles(player,roles,by_player_name,true) + assign_roles(player, 'Jail', by_player_name, nil, true) + unassign_roles(player, roles, by_player_name, nil, true) end local inv = player.get_main_inventory() @@ -202,8 +202,8 @@ function Jail.untemp_ban_player(player,by_player_name) if has_role(player,'Jail') then local roles = old_roles[player.name] - assign_roles(player,roles,by_player_name,true) - unassign_roles(player,'Jail',by_player_name,true) + assign_roles(player, roles, by_player_name, nil, true) + unassign_roles(player, 'Jail', by_player_name, nil, true) end event_emit(Jail.events.on_player_untemp_banned,player,by_player_name) From 7b1c5b6fa85c09e3f67f48844a243ff635574a84 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 4 Apr 2020 21:11:36 +0100 Subject: [PATCH 69/81] Added jail to discord alerts --- config/discord_alerts.lua | 10 +++--- modules/addons/discord-alerts.lua | 52 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/config/discord_alerts.lua b/config/discord_alerts.lua index 1d2c58d0..dc9c48c4 100644 --- a/config/discord_alerts.lua +++ b/config/discord_alerts.lua @@ -8,10 +8,12 @@ return { player_mutes=true, player_kicks=true, player_promotes=false, - config=true, - purge=true, - c=true, - command=true, + player_jail=true, + player_temp_ban=true, + ['config']=true, + ['purge']=true, + ['c']=true, + ['command']=true, ['silent-command']=true, ['measured-command']=true, ['banlist']=true, diff --git a/modules/addons/discord-alerts.lua b/modules/addons/discord-alerts.lua index f50271aa..59733767 100644 --- a/modules/addons/discord-alerts.lua +++ b/modules/addons/discord-alerts.lua @@ -129,6 +129,58 @@ if config.player_warnings then end) end +--- When a player is jailed or unjailed +if config.player_jail then + local Jail = require 'modules.control.jail' + Event.add(Jail.events.on_player_jailed,function(event) + local player_name = get_player_name(event) + emit_event{ + title='Jail', + description='A player has been jailed', + color=Colors.yellow, + ['Player:']=''..player_name, + ['By:']=''..event.by_player_name, + ['Reason:']=event.reason + } + end) + Event.add(Jail.events.on_player_unjailed,function(event) + local player_name = get_player_name(event) + emit_event{ + title='Unjail', + description='A player has been unjailed', + color=Colors.green, + ['Player:']=''..player_name, + ['By:']=''..event.by_player_name + } + end) +end + +--- When a player is tempbanned +if config.player_temp_ban then + local Jail = require 'modules.control.jail' + Event.add(Jail.events.on_player_temp_banned,function(event) + local player_name = get_player_name(event) + emit_event{ + title='Temp Ban', + description='A player has been temp banned', + color=Colors.red, + ['Player:']=''..player_name, + ['By:']=''..event.by_player_name, + ['Reason:']=event.reason + } + end) + Event.add(Jail.events.on_player_untemp_banned,function(event) + local player_name = get_player_name(event) + emit_event{ + title='Temp Ban Removed', + description='A player has been untemp banned', + color=Colors.green, + ['Player:']=''..player_name, + ['By:']=''..event.by_player_name + } + end) +end + --- Ban and unban if config.player_bans then Event.add(defines.events.on_player_banned,function(event) From ab2382fe96faf9fe548c58f49afbae5606ab66b4 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 4 Apr 2020 21:22:51 +0100 Subject: [PATCH 70/81] Fixed nil detail discord alerts --- modules/addons/discord-alerts.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/addons/discord-alerts.lua b/modules/addons/discord-alerts.lua index 59733767..4d97f29e 100644 --- a/modules/addons/discord-alerts.lua +++ b/modules/addons/discord-alerts.lua @@ -282,7 +282,7 @@ Event.add(defines.events.on_console_command,function(event) description='/'..event.command..' was used', color=Colors.grey, ['By:']=''..player_name, - ['Details:']=event.parameters + ['Details:'] = event.parameters ~= '' and event.parameters or nil } end end From 4acb7a06885cc3614f0247c296228460ad20585b Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 4 Apr 2020 21:31:08 +0100 Subject: [PATCH 71/81] Fixed discord alert colours --- modules/addons/discord-alerts.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/addons/discord-alerts.lua b/modules/addons/discord-alerts.lua index 4d97f29e..a76c4a79 100644 --- a/modules/addons/discord-alerts.lua +++ b/modules/addons/discord-alerts.lua @@ -20,7 +20,7 @@ local function to_hex(color) return hex_digits:sub(major,major)..hex_digits:sub(minor,minor) end - return hex(color.r)..hex(color.g)..hex(color.b) + return '0x'..hex(color.r)..hex(color.g)..hex(color.b) end local function emit_event(args) @@ -133,24 +133,24 @@ end if config.player_jail then local Jail = require 'modules.control.jail' Event.add(Jail.events.on_player_jailed,function(event) - local player_name = get_player_name(event) + local player_name,by_player_name = get_player_name(event) emit_event{ title='Jail', description='A player has been jailed', color=Colors.yellow, ['Player:']=''..player_name, - ['By:']=''..event.by_player_name, + ['By:']=''..by_player_name, ['Reason:']=event.reason } end) Event.add(Jail.events.on_player_unjailed,function(event) - local player_name = get_player_name(event) + local player_name,by_player_name = get_player_name(event) emit_event{ title='Unjail', description='A player has been unjailed', color=Colors.green, ['Player:']=''..player_name, - ['By:']=''..event.by_player_name + ['By:']=''..by_player_name } end) end @@ -159,24 +159,24 @@ end if config.player_temp_ban then local Jail = require 'modules.control.jail' Event.add(Jail.events.on_player_temp_banned,function(event) - local player_name = get_player_name(event) + local player_name,by_player_name = get_player_name(event) emit_event{ title='Temp Ban', description='A player has been temp banned', color=Colors.red, ['Player:']=''..player_name, - ['By:']=''..event.by_player_name, + ['By:']=''..by_player_name, ['Reason:']=event.reason } end) Event.add(Jail.events.on_player_untemp_banned,function(event) - local player_name = get_player_name(event) + local player_name,by_player_name = get_player_name(event) emit_event{ title='Temp Ban Removed', description='A player has been untemp banned', color=Colors.green, ['Player:']=''..player_name, - ['By:']=''..event.by_player_name + ['By:']=''..by_player_name } end) end From b05d5a9da61f8a75c763f728f4fe32eebb106c14 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 4 Apr 2020 21:49:06 +0100 Subject: [PATCH 72/81] Updated Github Readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c1ab73b8..851be090 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ All are welcome to make pull requests and issues for this scenario, if you are i | Scenario Version* | Version Name | Factorio Version** | |---|---|---| +| [v6.0][s6.0] | Gui / 0.18 Overhaul | [v0.18.17][f0.18.17] | | [v5.10][s5.10] | Data Store Rewrite | [v0.17.71][f0.17.71] | | [v5.9][s5.9] | Control Modules and Documentation | [v0.17.63][f0.17.63] | | [v5.8][s5.8] | Home and Chat Bot | [v0.17.47][f0.17.49] | @@ -79,6 +80,7 @@ All are welcome to make pull requests and issues for this scenario, if you are i \*\* Factorio versions show the version they were made for, often the minimum requirement. +[s6.0]: https://github.com/explosivegaming/scenario/releases/tag/6.0.0 [s5.10]: https://github.com/explosivegaming/scenario/releases/tag/5.10.0 [s5.9]: https://github.com/explosivegaming/scenario/releases/tag/5.9.0 [s5.8]: https://github.com/explosivegaming/scenario/releases/tag/5.8.0 @@ -96,6 +98,7 @@ All are welcome to make pull requests and issues for this scenario, if you are i [s1.0]: https://github.com/explosivegaming/scenario/releases/tag/v1.0 [s0.1]: https://github.com/explosivegaming/scenario/releases/tag/v0.1 +[f0.18.17]: https://wiki.factorio.com/Version_history/0.18.0#0.18.17 [f0.17.71]: https://wiki.factorio.com/Version_history/0.17.0#0.17.71 [f0.17.63]: https://wiki.factorio.com/Version_history/0.17.0#0.17.63 [f0.17.49]: https://wiki.factorio.com/Version_history/0.17.0#0.17.49 From 05e5a187b0de8203e4d19b36ce2b656880eb5d5d Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sat, 4 Apr 2020 22:40:19 +0100 Subject: [PATCH 73/81] Inconsistent type check in store.map --- expcore/store.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expcore/store.lua b/expcore/store.lua index 735ccef4..ffb2afa8 100644 --- a/expcore/store.lua +++ b/expcore/store.lua @@ -453,7 +453,7 @@ function Store.map(store,updater) -- Get all that data in the store and check its a table local data = data_store[store] - if not type(data) == 'table' then + if type(data) ~= 'table' then return end From 8569de50aa38c9592c7f74711ae20540fa6778a2 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 5 Apr 2020 19:39:19 +0100 Subject: [PATCH 74/81] Moved map time to info gui --- config/chat_reply.lua | 4 ---- locale/en/addons.cfg | 1 - locale/en/gui.cfg | 2 +- modules/gui/readme.lua | 4 +++- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/config/chat_reply.lua b/config/chat_reply.lua index d4b66a16..2f653569 100644 --- a/config/chat_reply.lua +++ b/config/chat_reply.lua @@ -24,7 +24,6 @@ return { ['softmod']={'info.softmod'}, ['script']={'info.softmod'}, ['loop']={'chat-bot.loops'}, - ['loops']={'chat-bot.loops'}, ['rhd']={'info.lhd'}, ['lhd']={'info.lhd'}, ['roundabout']={'chat-bot.loops'}, @@ -45,9 +44,6 @@ return { ['online']=function() return {'chat-bot.players-online',#game.connected_players} end, - ['time']=function() - return {'chat-bot.map-time',format_time(game.tick,{days=true,hours=true,minutes=true,seconds=true,long=true})} - end, ['r!verify']=function(player) return {'chat-bot.verify',player.name} end, diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index 9281e461..4cb4c837 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -47,7 +47,6 @@ reply=[Chat Bot] __1__ disallow=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__ not-real-dev=Cooldude2606 is a dev for this server and makes the softmod and is not a factorio dev. softmod=A softmod is a custom scenario that runs on this server,an example is the player list. blame=Blame __1__ for what just happened! diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 15e4c113..5586782d 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -102,7 +102,7 @@ goto-edit=Edit warp icon main-tooltip=Infomation welcome-tab=Welcome welcome-tooltip=Welcome to Explosive Gaming -welcome-general=Welcome to Explosive Gaming, we host many factorio servers. While you are here we require you to follow our rules, you can find these in the tab above. You can also find our custom commands and links to our other servers.\nPlease note that our servers reset periodically, the next reset is: __1__ +welcome-general=Welcome to Explosive Gaming, we host many factorio servers. While you are here we require you to follow our rules, you can find these in the tab above. You can also find our custom commands and links to our other servers. This map has been online for __2__.\nPlease note that our servers reset periodically, the next reset is: __1__ welcome-roles=We run a custom role system to help protect the work of others. As a result you may not be able to use your deconstruction planner yet or drop item on the groud. Roles also give you access to some custom features such as adding tasks to our task list or making new warp points.\nYou have been assigned the roles: __1__ welcome-chat=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.\nThe setting you need to change is “Toggle chat (and Lua console)” you currently have it set to "__CONTROL__toggle-console__" rules-tab=Rules diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index 18c094af..35691dd9 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -9,6 +9,7 @@ local Roles = require 'expcore.roles' --- @dep expcore.roles local Commands = require 'expcore.commands' --- @dep expcore.commands local Event = require 'utils.event' --- @dep utils.event local Game = require 'utils.game' --- @dep utils.game +local format_time = _C.format_time --- @dep expcore.common local tabs = {} local function Tab(caption,tooltip,element_define) @@ -98,7 +99,8 @@ Gui.element(function(_,parent) -- Add the other information to the gui container.add{ type='flow' }.style.height = 4 - Gui.centered_label(sub_content(container), frame_width, {'readme.welcome-general', server_details.reset_time}) + local online_time = format_time(game.tick,{days=true,hours=true,minutes=true,long=true}) + Gui.centered_label(sub_content(container), frame_width, {'readme.welcome-general', server_details.reset_time, online_time}) Gui.centered_label(sub_content(container), frame_width, {'readme.welcome-roles', table.concat(role_names,', ')}) Gui.centered_label(sub_content(container), frame_width, {'readme.welcome-chat'}) From 44a09d09919891cedd1d5c36597d69fd617f3aad Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 5 Apr 2020 21:33:52 +0100 Subject: [PATCH 75/81] Fixed rocket progress status --- modules/control/production.lua | 2 +- modules/control/rockets.lua | 4 +++- modules/gui/rocket-info.lua | 12 ++++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/modules/control/production.lua b/modules/control/production.lua index f6e6c1c2..026bad7c 100644 --- a/modules/control/production.lua +++ b/modules/control/production.lua @@ -33,7 +33,7 @@ ]] local Colors = require 'utils.color_presets' --- @dep utils.color_presets -local format_number = _C.format_number --- @dep util +local format_number = require('util').format_number --- @dep util local precision_index = defines.flow_precision_index local Production = {} diff --git a/modules/control/rockets.lua b/modules/control/rockets.lua index 0dff7f84..a09c74ce 100644 --- a/modules/control/rockets.lua +++ b/modules/control/rockets.lua @@ -135,12 +135,14 @@ end function Rockets.get_rolling_average(force_name,count) local force = game.forces[force_name] local rocket_count = force.rockets_launched + if rocket_count == 0 then return 0 end + local last_launch_time = rocket_times[force_name][rocket_count] local start_rocket_time = 0 if count < rocket_count then start_rocket_time = rocket_times[force_name][rocket_count-count+1] rocket_count = count end - return rocket_count > 0 and math.floor((game.tick-start_rocket_time)/rocket_count) or 0 + return math.floor((last_launch_time-start_rocket_time)/rocket_count) end --- Event used to update the stats and the hui when a rocket is launched diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index 2081cb9e..c15ea688 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -73,11 +73,7 @@ Gui.element{ local rocket_silo_name = element.parent.name:sub(8) local silo_data = Rockets.get_silo_data_by_name(rocket_silo_name) if silo_data.entity.launch_rocket() then - silo_data.awaiting_reset = true element.enabled = false - local progress_label = element.parent.parent[rocket_silo_name].label - progress_label.caption = {'rocket-info.progress-launched'} - progress_label.style.font_color = Colors.green else player.print({'rocket-info.launch-failed'},Colors.orange_red) end @@ -555,6 +551,14 @@ local function update_rocket_gui_progress(force_name) end end +--- Event used to set a rocket silo to be awaiting reset +Event.add(defines.events.on_rocket_launch_ordered,function(event) + local silo = event.rocket_silo + local silo_data = Rockets.get_silo_data(silo) + silo_data.awaiting_reset = true + update_rocket_gui_progress(silo.force.name) +end) + Event.on_nth_tick(150,function() for _,force in pairs(game.forces) do if #Rockets.get_silos(force.name) > 0 then From 9214cc5239466ebd08ad36ec003b776e2b48d284 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 7 Apr 2020 17:38:54 +0100 Subject: [PATCH 76/81] Fixed tasklist bug --- expcore/gui/left_flow.lua | 8 +++++++- locale/en/gui.cfg | 2 +- modules/gui/server-ups.lua | 6 +++--- modules/gui/task-list.lua | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index f57dac1a..4befce31 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -93,7 +93,13 @@ function Gui.draw_left_flow(player) for name, open_on_join in pairs(Gui.left_elements) do -- Draw the element to the left flow - local left_element = Gui.defines[name](left_flow) + local draw_success, left_element = pcall(function() + return Gui.defines[name](left_flow) + end) + + if not draw_success then + error('There as been an error with an element draw function:\n\t'..left_element) + end -- Check if it should be open by default local visible = type(open_on_join) == 'boolean' and open_on_join or false diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 5586782d..987cd10f 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -102,7 +102,7 @@ goto-edit=Edit warp icon main-tooltip=Infomation welcome-tab=Welcome welcome-tooltip=Welcome to Explosive Gaming -welcome-general=Welcome to Explosive Gaming, we host many factorio servers. While you are here we require you to follow our rules, you can find these in the tab above. You can also find our custom commands and links to our other servers. This map has been online for __2__.\nPlease note that our servers reset periodically, the next reset is: __1__ +welcome-general=Welcome to Explosive Gaming; we host many factorio servers. While you are here, we require you to follow our rules. You can find these in the tab above. You can also find our custom commands and links to our other servers. This map has been online for __2__.\nPlease note that our servers reset periodically, the next reset is: __1__ welcome-roles=We run a custom role system to help protect the work of others. As a result you may not be able to use your deconstruction planner yet or drop item on the groud. Roles also give you access to some custom features such as adding tasks to our task list or making new warp points.\nYou have been assigned the roles: __1__ welcome-chat=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.\nThe setting you need to change is “Toggle chat (and Lua console)” you currently have it set to "__CONTROL__toggle-console__" rules-tab=Rules diff --git a/modules/gui/server-ups.lua b/modules/gui/server-ups.lua index cba75d89..29ca6542 100644 --- a/modules/gui/server-ups.lua +++ b/modules/gui/server-ups.lua @@ -13,7 +13,7 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands local server_ups = Gui.element{ type = 'label', - caption = 'Server UPS = 60.0' + caption = 'SUPS = 60.0' } :style{ font = 'default-game' @@ -38,7 +38,7 @@ local function set_location(event) local label = player.gui.screen[server_ups.name] local res = player.display_resolution local uis = player.display_scale - label.location = { x=res.width-465*uis, y=30*uis } + label.location = { x=res.width-423*uis, y=30*uis } end -- Draw the label when the player joins @@ -52,7 +52,7 @@ end) -- Update the caption for all online players Event.on_nth_tick(60,function() if global.ext and global.ext.server_ups then - local caption = 'Server UPS = '..global.ext.server_ups + local caption = 'SUPS = '..global.ext.server_ups for _,player in pairs(game.connected_players) do player.gui.screen[server_ups.name].caption = caption end diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index 19c3906d..20f3f189 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -341,7 +341,7 @@ Gui.element(function(event_trigger,parent) -- Add any existing tasks local task_ids = Tasks.get_force_task_ids(player.force.name) if #task_ids > 0 then - no_tasks_style.visible = false + no_tasks_label.visible = false for _,task_id in ipairs(task_ids) do update_task(player,scroll_table,task_id) end From b04d7fe04013de89500525801cff2bab40e9c5c7 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 8 Apr 2020 15:32:41 +0100 Subject: [PATCH 77/81] Number of bug fixes --- config/expcore/permission_groups.lua | 2 +- config/expcore/roles.lua | 1 + modules/addons/tree-decon.lua | 32 +++++++++++++++++++++------- modules/gui/player-list.lua | 8 ++++++- modules/gui/readme.lua | 8 +++++++ 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/config/expcore/permission_groups.lua b/config/expcore/permission_groups.lua index 812584b7..236268b4 100644 --- a/config/expcore/permission_groups.lua +++ b/config/expcore/permission_groups.lua @@ -85,7 +85,7 @@ Permission_Groups.new_group('Guest') 'set_auto_launch_rocket', 'change_programmable_speaker_parameters', -- guest 'change_train_stop_station', - 'deconstruct', + --'deconstruct', 'remove_cables', 'remove_train_station', 'reset_assembling_machine', diff --git a/config/expcore/roles.lua b/config/expcore/roles.lua index 236fa347..763fd132 100644 --- a/config/expcore/roles.lua +++ b/config/expcore/roles.lua @@ -197,6 +197,7 @@ Roles.new_role('Regular','Reg') 'command/rainbow', 'command/go-to-spawn', 'command/me', + 'standard-decon' } :set_auto_assign_condition(function(player) if player.online_time > 3*216000 then diff --git a/modules/addons/tree-decon.lua b/modules/addons/tree-decon.lua index ac065342..ea7bfb8f 100644 --- a/modules/addons/tree-decon.lua +++ b/modules/addons/tree-decon.lua @@ -16,21 +16,37 @@ end) -- Add trees to queue when marked, only allows simple entities and for players with role permission Event.add(defines.events.on_marked_for_deconstruction, function(event) - -- Check the player is allowed fast decon - local player = Game.get_player_by_index(event.player_index) - if chache[player.name] ~= true and not Roles.player_allowed(player, 'fast-tree-decon') then - chache[player.name] = false + -- Check which type of decon a player is allowed + local index = event.player_index + if chache[index] == nil then + local player = Game.get_player_by_index(index) + if Roles.player_allowed(player, 'fast-tree-decon') then chache[index] = 'fast' + elseif Roles.player_allowed(player, 'standard-decon') then chache[index] = 'standard' + else chache[index] = player.force end + end + + -- Check what should happen to this entity + local entity = event.entity + local allow = chache[index] + if not entity or not entity.valid then return end + + -- Not allowed to decon this entity + local last_user = entity.last_user + if last_user and allow ~= 'standard' and allow ~= 'fast' then + entity.cancel_deconstruction(allow) return end - chache[player.name] = true - -- Check that the entity is allowed to be isntant deconed + -- Allowed to decon this entity, but not fast + if allow ~= 'fast' then return end + + -- Allowed fast decon on this entity, just trees local head = tree_queue._head + 1 - local entity = event.entity - if entity and entity.valid and not entity.last_user and entity.type ~= 'cliff' then + if not last_user and entity.type ~= 'cliff' then tree_queue[head] = entity tree_queue._head = head end + end) -- Remove trees at random till the queue is empty diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index d16acd5e..fce43c57 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -94,7 +94,7 @@ Gui.element(function(event_trigger,parent,player_data) open_action_bar(toggle_action_bar_flow) -- Add the player name - local player_name_flow = parent.add{ type = 'flow', 'player-name-'..player_data.index } + local player_name_flow = parent.add{ type = 'flow', name = 'player-name-'..player_data.index } local player_name = player_name_flow.add{ type = 'label', name = event_trigger, @@ -364,6 +364,12 @@ Event.add(defines.events.on_player_left_game,function(event) local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table remove_player_base(scroll_table,remove_player) + + local selected_player_name = Store.get(selected_player_store,player) + if selected_player_name == remove_player.name then + Store.clear(selected_player_store,player) + Store.clear(selected_action_store,player) + end end end) diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index 35691dd9..1f8e8ad4 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -333,4 +333,12 @@ Event.add(defines.events.on_player_joined_game,function(event) if not player.opened then player.gui.center.clear() end +end) + +--- When a player respawns clear center unless the player has something open +Event.add(defines.events.on_player_respawned,function(event) + local player = Game.get_player_by_index(event.player_index) + if not player.opened then + player.gui.center.clear() + end end) \ No newline at end of file From c450bda23441faef50b46384a39924e539f678cb Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 8 Apr 2020 18:11:07 +0100 Subject: [PATCH 78/81] Changed Readme Text --- locale/en/gui.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 987cd10f..4adc9626 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -102,7 +102,7 @@ goto-edit=Edit warp icon main-tooltip=Infomation welcome-tab=Welcome welcome-tooltip=Welcome to Explosive Gaming -welcome-general=Welcome to Explosive Gaming; we host many factorio servers. While you are here, we require you to follow our rules. You can find these in the tab above. You can also find our custom commands and links to our other servers. This map has been online for __2__.\nPlease note that our servers reset periodically, the next reset is: __1__ +welcome-general=Welcome to Explosive Gaming; we host many factorio servers. While you are here, we ask you to follow our rules. You can find these in the tab above. You can also find our custom commands and links to our other servers. This map has been online for __2__.\nPlease note that our servers reset periodically, the next reset is: __1__ welcome-roles=We run a custom role system to help protect the work of others. As a result you may not be able to use your deconstruction planner yet or drop item on the groud. Roles also give you access to some custom features such as adding tasks to our task list or making new warp points.\nYou have been assigned the roles: __1__ welcome-chat=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.\nThe setting you need to change is “Toggle chat (and Lua console)” you currently have it set to "__CONTROL__toggle-console__" rules-tab=Rules @@ -128,7 +128,7 @@ commands-tooltip=Commands which you are able to use commands-general=We have lots of custom commands which you are able to use. Below you can find a list of all the commands that you are allowed to use and what they do. If you need more information or want to search for a command you can use our /search-help command. servers-tab=Servers servers-tooltip=Links to our other servers and sites -servers-general=This is only one of our servers for factorio, we host alot of others as well. Below you can find details about all the servers that we host as well as links to our external services such as discord or github. +servers-general=This is only one of our servers for factorio, we host many of others as well. Below you can find details about all the servers that we host as well as links to our external services such as discord or github. servers-factorio=Factorio Servers servers-1=S1 Public servers-d1=This is our 48 hour reset experimental server. @@ -150,7 +150,7 @@ servers-external=External Links servers-open-in-browser=Open in your browser backers-tab=Backers backers-tooltip=People who have helped make our server -backers-general=We would like to thank all our staff and backers who have helped our comunity grow. Our staff have helped to keep our servers safe from trolls and fun places to play. Our backers have helped us to cover our running costs and provide a great comunity for us all to enjoy together. +backers-general=We would like to thank all our staff and backers who have helped our community grow. Our staff have helped to keep our servers safe from trolls and a fun place to play. Our backers have helped us to cover our running costs and provide a great community for us all to enjoy together. backers-management=Administrators backers-board=Board Members and Senior Backers backers-staff=Staff Members From 24b2b0703e67b46be6b8761de50d5e0893882436 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 8 Apr 2020 19:50:40 +0100 Subject: [PATCH 79/81] Fixed chat popup for server --- modules/addons/chat-popups.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/addons/chat-popups.lua b/modules/addons/chat-popups.lua index 1ff2b107..d27672a6 100644 --- a/modules/addons/chat-popups.lua +++ b/modules/addons/chat-popups.lua @@ -9,6 +9,7 @@ local config = require 'config.popup_messages' --- @dep config.popup_messages local send_text = Game.print_player_floating_text -- (player_index, text, color) Event.add(defines.events.on_console_chat,function(event) + if not event.player_index or event.player_index < 1 then return end local player = Game.get_player_by_index(event.player_index) -- Some basic sanity checks From 4591f441b76cccbc9df666b6b59970151a87b33a Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 8 Apr 2020 20:10:46 +0100 Subject: [PATCH 80/81] Fixed tree decon error --- modules/addons/tree-decon.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/addons/tree-decon.lua b/modules/addons/tree-decon.lua index ea7bfb8f..75f5738b 100644 --- a/modules/addons/tree-decon.lua +++ b/modules/addons/tree-decon.lua @@ -56,7 +56,7 @@ Event.add(defines.events.on_tick, function() local max_remove = math.floor(head/100)+1 local remove_count = math.random(0, max_remove) - while remove_count > 0 do + while remove_count > 0 and head > 0 do local remove_index = math.random(1,head) local entity = tree_queue[remove_index] tree_queue[remove_index] = tree_queue[head] From 8b1db536fe308a32347983dfcee02b3fdccfcb9d Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 8 Apr 2020 20:23:03 +0100 Subject: [PATCH 81/81] Fixed Player List Not Removing --- modules/gui/player-list.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index fce43c57..3eea3587 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -359,7 +359,7 @@ end) --- When a player leaves only remove they entry Event.add(defines.events.on_player_left_game,function(event) - local remove_player = event.player + local remove_player = Game.get_player_by_index(event.player_index) for _,player in pairs(game.connected_players) do local frame = Gui.get_left_element(player,player_list_container) local scroll_table = frame.container.scroll.table