You've already forked ComfyFactorio
							
							
				mirror of
				https://github.com/ComfyFactory/ComfyFactorio.git
				synced 2025-10-30 23:47:41 +02:00 
			
		
		
		
	Small commands refactor
This commit is contained in:
		| @@ -13,7 +13,7 @@ require 'utils.table' | ||||
| require 'utils.whisper_notice' | ||||
| require 'utils.datastore.init' | ||||
| require 'utils.chatbot' | ||||
| require 'utils.commands' | ||||
| require 'utils.common_commands' | ||||
| require 'utils.antigrief' | ||||
| require 'utils.debug.command' | ||||
| require 'modules.corpse_markers' | ||||
|   | ||||
| @@ -1,375 +1,209 @@ | ||||
| local Color = require 'utils.color_presets' | ||||
| local Public = require 'maps.mountain_fortress_v3.table' | ||||
| local Task = require 'utils.task' | ||||
| local Server = require 'utils.server' | ||||
| local Collapse = require 'modules.collapse' | ||||
| local WD = require 'modules.wave_defense.table' | ||||
| local Discord = require 'utils.discord_handler' | ||||
| local Commands = require 'utils.commands' | ||||
| local mapkeeper = '[color=blue]Mapkeeper:[/color]' | ||||
| local scenario_name = Public.scenario_name | ||||
|  | ||||
| commands.add_command( | ||||
|     'scenario', | ||||
|     'Usable only for admins - controls the scenario!', | ||||
|     function(cmd) | ||||
|         local p | ||||
|         local player = game.player | ||||
|  | ||||
|         if not player or not player.valid then | ||||
|             p = log | ||||
|         else | ||||
|             p = player.print | ||||
|             if not player.admin then | ||||
|                 return | ||||
|             end | ||||
|         end | ||||
|  | ||||
|         local this = Public.get() | ||||
|         local param = cmd.parameter | ||||
|  | ||||
|         if param == 'restart' or param == 'shutdown' or param == 'reset' or param == 'restartnow' then | ||||
|             goto continue | ||||
|         else | ||||
|             p('[ERROR] Arguments are:\nrestart\nshutdown\nreset\nrestartnow') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         ::continue:: | ||||
|  | ||||
|         if not this.reset_are_you_sure then | ||||
|             this.reset_are_you_sure = true | ||||
|             p('[WARNING] This command will disable the soft-reset feature, run this command again if you really want to do this!') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == 'restart' then | ||||
|             if this.restart then | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 this.restart = false | ||||
|                 this.soft_reset = true | ||||
|                 p('[SUCCESS] Soft-reset is enabled.') | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' has enabled soft-reset!') | ||||
|                 return | ||||
|             else | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 this.restart = true | ||||
|                 this.soft_reset = false | ||||
|                 if this.shutdown then | ||||
|                     this.shutdown = false | ||||
|                 end | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' has disabled soft-reset! Restart will happen from scenario.') | ||||
|                 p('[WARNING] Soft-reset is disabled! Server will restart from scenario to load new changes.') | ||||
|                 return | ||||
|             end | ||||
|         elseif param == 'restartnow' then | ||||
|             this.reset_are_you_sure = nil | ||||
|             Server.start_scenario('Mountain_Fortress_v3') | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' restarted the scenario.') | ||||
|             return | ||||
|         elseif param == 'shutdown' then | ||||
|             if this.shutdown then | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 this.shutdown = false | ||||
|                 this.soft_reset = true | ||||
|                 p('[SUCCESS] Soft-reset is enabled.') | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' has enabled soft-reset. Server will NOT shutdown!') | ||||
|                 return | ||||
|             else | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 this.shutdown = true | ||||
|                 this.soft_reset = false | ||||
|                 if this.restart then | ||||
|                     this.restart = false | ||||
|                 end | ||||
|                 p('[WARNING] Soft-reset is disabled! Server will shutdown. Most likely because of updates.') | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' has disabled soft-reset. Server will shutdown!') | ||||
|                 return | ||||
|             end | ||||
|         elseif param == 'reset' then | ||||
|             this.reset_are_you_sure = nil | ||||
|             if player and player.valid then | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has reset the game!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' has reset the game!') | ||||
|             else | ||||
|                 game.print(mapkeeper .. ' server, has reset the game!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|                 Discord.send_notification_raw(scenario_name, 'Server has reset the game!') | ||||
|             end | ||||
|             Public.reset_map() | ||||
|             p('[WARNING] Game has been reset!') | ||||
|             return | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'set_queue_speed', | ||||
|     'Usable only for admins - sets the queue speed of this map!', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
|         local param = tonumber(cmd.parameter) | ||||
|  | ||||
|         if player and player.valid then | ||||
|             if not player.admin then | ||||
|                 player.print("[ERROR] You're not admin!", Color.fail) | ||||
|                 return | ||||
|             end | ||||
|             if not param then | ||||
|                 return | ||||
|             end | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' set the queue speed to: ' .. param) | ||||
|             player.print('Queue speed set to: ' .. param) | ||||
|             Task.set_queue_speed(param) | ||||
|         else | ||||
|             log('Queue speed set to: ' .. param) | ||||
|             Task.set_queue_speed(param) | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'complete_quests', | ||||
|     'Usable only for admins - sets the queue speed of this map!', | ||||
|     function() | ||||
|         local player = game.player | ||||
|  | ||||
|         if player and player.valid then | ||||
|             if not player.admin then | ||||
|                 player.print("[ERROR] You're not admin!", Color.fail) | ||||
|                 return | ||||
|             end | ||||
| Commands.new('scenario', 'Usable only for admins - controls the scenario!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :add_parameter('restart/shutdown/reset/restartnow', false, 'string') | ||||
|     :callback( | ||||
|         function (player, action) | ||||
|             local this = Public.get() | ||||
|             if not this.reset_are_you_sure then | ||||
|                 this.reset_are_you_sure = true | ||||
|                 player.print('[WARNING] This command will break the current run and complete all quests, run this command again if you really want to do this!', Color.warning) | ||||
|                 return | ||||
|  | ||||
|             if action == 'restart' or action == 'shutdown' or action == 'reset' or action == 'restartnow' then | ||||
|                 goto continue | ||||
|             else | ||||
|                 player.print('Invalid action.') | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
|             this.reset_are_you_sure = nil | ||||
|             ::continue:: | ||||
|  | ||||
|             if action == 'restart' then | ||||
|                 if this.restart then | ||||
|                     this.reset_are_you_sure = nil | ||||
|                     this.restart = false | ||||
|                     this.soft_reset = true | ||||
|                     Discord.send_notification_raw(scenario_name, player.name .. ' has enabled soft-reset!') | ||||
|                     player.print('Soft-reset is enabled.') | ||||
|                 else | ||||
|                     this.reset_are_you_sure = nil | ||||
|                     this.restart = true | ||||
|                     this.soft_reset = false | ||||
|                     if this.shutdown then | ||||
|                         this.shutdown = false | ||||
|                     end | ||||
|                     Discord.send_notification_raw(scenario_name, player.name .. ' has disabled soft-reset! Restart will happen from scenario.') | ||||
|                     player.print('Soft-reset is disabled! Server will restart from scenario to load new changes.') | ||||
|                 end | ||||
|             elseif action == 'restartnow' then | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 Server.start_scenario('Mountain_Fortress_v3') | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' restarted the scenario.') | ||||
|                 player.print('Restarted the scenario.') | ||||
|             elseif action == 'shutdown' then | ||||
|                 if this.shutdown then | ||||
|                     this.reset_are_you_sure = nil | ||||
|                     this.shutdown = false | ||||
|                     this.soft_reset = true | ||||
|                     Discord.send_notification_raw(scenario_name, | ||||
|                         player.name .. ' has enabled soft-reset. Server will NOT shutdown!') | ||||
|  | ||||
|                     player.print('Soft-reset is enabled.') | ||||
|                 else | ||||
|                     this.reset_are_you_sure = nil | ||||
|                     this.shutdown = true | ||||
|                     this.soft_reset = false | ||||
|                     if this.restart then | ||||
|                         this.restart = false | ||||
|                     end | ||||
|  | ||||
|                     Discord.send_notification_raw(scenario_name, player.name .. ' has disabled soft-reset. Server will shutdown!') | ||||
|                     player.print('Soft-reset is disabled! Server will shutdown.') | ||||
|                 end | ||||
|             elseif action == 'reset' then | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 if player and player.valid then | ||||
|                     game.print(mapkeeper .. ' ' .. player.name .. ', has reset the game!', | ||||
|                         { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|                     Discord.send_notification_raw(scenario_name, player.name .. ' has reset the game!') | ||||
|                 else | ||||
|                     game.print(mapkeeper .. ' server, has reset the game!', { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|                     Discord.send_notification_raw(scenario_name, 'Server has reset the game!') | ||||
|                 end | ||||
|                 Public.reset_map() | ||||
|                 player.print('Game has been reset!') | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| Commands.new('mtn_set_queue_speed', 'Usable only for admins - sets the queue speed of this map!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :add_parameter('speed', true, 'number') | ||||
|     :callback( | ||||
|         function (player, speed) | ||||
|             Task.set_queue_speed(speed) | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' set the queue speed to: ' .. speed) | ||||
|             player.print('Queue speed set to: ' .. speed) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| Commands.new('mtn_complete_quests', 'Usable only for admins - sets the queue speed of this map!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' completed all the quest via command.') | ||||
|             Public.stateful.set_stateful('objectives_completed_count', 6) | ||||
|             game.print(mapkeeper .. player.name .. ', has forced completed all quests!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|         else | ||||
|             local this = Public.get() | ||||
|             if not this.reset_are_you_sure then | ||||
|                 this.reset_are_you_sure = true | ||||
|                 log('[WARNING] This command will break the current run and complete all quests, run this command again if you really want to do this!') | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             this.reset_are_you_sure = nil | ||||
|             log('Quests completed.') | ||||
|             Discord.send_notification_raw(scenario_name, 'Server completed all the quest via command') | ||||
|             Public.stateful.set_stateful('objectives_completed_count', 6) | ||||
|             game.print(mapkeeper .. player.name .. ', has forced completed all quests!', { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|             player.print('Quests completed.') | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'reverse_map', | ||||
|     'Usable only for admins - reverses the map!', | ||||
|     function() | ||||
|         local player = game.player | ||||
|  | ||||
|         if player and player.valid then | ||||
|             if not player.admin then | ||||
|                 player.print("[ERROR] You're not admin!", Color.fail) | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             local this = Public.get() | ||||
|             if not this.reset_are_you_sure then | ||||
|                 this.reset_are_you_sure = true | ||||
|                 player.print('[WARNING] This command will reverse the map and soft-reset!', Color.warning) | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             this.reset_are_you_sure = nil | ||||
|     ) | ||||
|  | ||||
| Commands.new('mtn_reverse_map', 'Usable only for admins - reverses the map!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             local reversed = Public.get_stateful_settings('reversed') | ||||
|             Public.set_stateful_settings('reversed', not reversed) | ||||
|  | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' reversed the map.') | ||||
|             Public.reset_map() | ||||
|             game.print(mapkeeper .. player.name .. ', has reverse the map and reset the game!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|         else | ||||
|             game.print(mapkeeper .. player.name .. ', has reverse the map and reset the game!', | ||||
|                 { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|             player.print('Map reversed.') | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| Commands.new('mtn_disable_biters', 'Usable only for admins - disables wave defense!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             local tbl = WD.get() | ||||
|  | ||||
|             if not tbl.game_lost then | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' disabled the wave defense module.') | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has disabled the wave_defense module!', | ||||
|                     { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|                 tbl.game_lost = true | ||||
|             else | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' enabled the wave defense module.') | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has enabled the wave_defense module!', | ||||
|                     { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|                 tbl.game_lost = false | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| Commands.new('mtn_toggle_orbital_strikes', | ||||
|     'Usable only for admins - toggles orbital strikes!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             local this = Public.get() | ||||
|             if not this.reset_are_you_sure then | ||||
|                 this.reset_are_you_sure = true | ||||
|                 log('[WARNING] This command will reverse the map and soft-reset!') | ||||
|                 return | ||||
|  | ||||
|             if this.orbital_strikes.enabled then | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' disabled the orbital strike module.') | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has disabled the orbital_strikes module!', | ||||
|                     { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|                 this.orbital_strikes.enabled = false | ||||
|             else | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' enabled the orbital strike module.') | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has enabled the orbital_strikes module!', | ||||
|                     { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|                 this.orbital_strikes.enabled = true | ||||
|             end | ||||
|  | ||||
|             this.reset_are_you_sure = nil | ||||
|  | ||||
|             local reversed = Public.get_stateful_settings('reversed') | ||||
|             Public.set_stateful_settings('reversed', not reversed) | ||||
|  | ||||
|             Discord.send_notification_raw(scenario_name, 'script has reversed the map.') | ||||
|             Public.reset_map() | ||||
|             game.print(mapkeeper .. 'script, has reverse the map and reset the game!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'disable_biters', | ||||
|     'Usable only for admins - disables wave defense!', | ||||
|     function() | ||||
|         local player = game.player | ||||
| Commands.new('mtn_toggle_end_game', 'Usable only for admins - initiates the final battle!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' toggled the end game.') | ||||
|             Public.stateful.set_stateful('final_battle', true) | ||||
|             Public.set('final_battle', true) | ||||
|  | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|             game.print(mapkeeper .. ' ' .. player.name .. ', has triggered the final battle sequence!', | ||||
|                 { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|         end | ||||
|         if not player.admin then | ||||
|             player.print("[ERROR] You're not admin!", Color.fail) | ||||
|             return | ||||
|     ) | ||||
|  | ||||
| Commands.new('mtn_get_queue_speed', 'Usable only for admins - gets the queue speed of this map!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             player.print(Task.get_queue_speed()) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         local this = Public.get() | ||||
|         local tbl = WD.get() | ||||
|  | ||||
|         if not this.disable_biters_are_you_sure then | ||||
|             this.disable_biters_are_you_sure = true | ||||
|             player.print('[WARNING] This command will disable the wave_defense in-game, run this command again if you really want to do this!', Color.warning) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if not tbl.game_lost then | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' disabled the wave defense module.') | ||||
|             game.print(mapkeeper .. ' ' .. player.name .. ', has disabled the wave_defense module!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|             tbl.game_lost = true | ||||
|         else | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' enabled the wave defense module.') | ||||
|             game.print(mapkeeper .. ' ' .. player.name .. ', has enabled the wave_defense module!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|             tbl.game_lost = false | ||||
|         end | ||||
|  | ||||
|         this.disable_biters_are_you_sure = nil | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'toggle_orbital_strikes', | ||||
|     'Usable only for admins - toggles orbital strikes!', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|         if not player.admin then | ||||
|             player.print("[ERROR] You're not admin!", Color.fail) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local this = Public.get() | ||||
|  | ||||
|         if not this.orbital_strikes_are_you_sure then | ||||
|             this.orbital_strikes_are_you_sure = true | ||||
|             player.print('[WARNING] This command will disable the orbital_strikes in-game, run this command again if you really want to do this!', Color.warning) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if this.orbital_strikes.enabled then | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' disabled the orbital strike module.') | ||||
|             game.print(mapkeeper .. ' ' .. player.name .. ', has disabled the orbital_strikes module!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|             this.orbital_strikes.enabled = false | ||||
|         else | ||||
|             Discord.send_notification_raw(scenario_name, player.name .. ' enabled the orbital strike module.') | ||||
|             game.print(mapkeeper .. ' ' .. player.name .. ', has enabled the orbital_strikes module!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|             this.orbital_strikes.enabled = true | ||||
|         end | ||||
|  | ||||
|         this.orbital_strikes_are_you_sure = nil | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'toggle_end_game', | ||||
|     'Usable only for admins - initiates the final battle!', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|         if not player.admin then | ||||
|             player.print("[ERROR] You're not admin!", Color.fail) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local this = Public.get() | ||||
|  | ||||
|         if not this.final_battle_are_you_sure then | ||||
|             this.final_battle_are_you_sure = true | ||||
|             player.print('[WARNING] This command will trigger the final battle, ONLY run this command again if you really want to do this!', Color.warning) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         Discord.send_notification_raw(scenario_name, player.name .. ' toggled the end game.') | ||||
|         Public.stateful.set_stateful('final_battle', true) | ||||
|         Public.set('final_battle', true) | ||||
|  | ||||
|         game.print(mapkeeper .. ' ' .. player.name .. ', has triggered the final battle sequence!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|  | ||||
|         this.final_battle_are_you_sure = nil | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'get_queue_speed', | ||||
|     'Usable only for admins - gets the queue speed of this map!', | ||||
|     function() | ||||
|         local p | ||||
|         local player = game.player | ||||
|  | ||||
|         if player and player.valid then | ||||
|             p = player.print | ||||
|             if not player.admin then | ||||
|                 p("[ERROR] You're not admin!", Color.fail) | ||||
|                 return | ||||
|             end | ||||
|             p(Task.get_queue_speed()) | ||||
|         else | ||||
|             p = log | ||||
|             p(Task.get_queue_speed()) | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'disable_collapse', | ||||
|     'Toggles the collapse feature', | ||||
|     function() | ||||
|         local player = game.player | ||||
|  | ||||
|         if player and player.valid then | ||||
|             if not player.admin then | ||||
|                 player.print("[ERROR] You're not admin!", Color.fail) | ||||
|                 return | ||||
|             end | ||||
| Commands.new('mtn_disable_collapse', 'Usable only for admins - toggles the collapse feature!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             if not Collapse.has_collapse_started() then | ||||
|                 Collapse.start_now(true, false) | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' has enabled collapse.') | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has enabled collapse!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|                 log(player.name .. ', has enabled collapse!') | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has enabled collapse!', { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|             else | ||||
|                 Collapse.start_now(false, true) | ||||
|                 Discord.send_notification_raw(scenario_name, player.name .. ' has disabled collapse.') | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has disabled collapse!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|                 log(player.name .. ', has disabled collapse!') | ||||
|             end | ||||
|         else | ||||
|             if not Collapse.has_collapse_started() then | ||||
|                 Collapse.start_now(true, false) | ||||
|                 Discord.send_notification_raw(scenario_name, 'Server has enabled collapse.') | ||||
|                 log('Collapse has started.') | ||||
|             else | ||||
|                 Collapse.start_now(false, true) | ||||
|                 Discord.send_notification_raw(scenario_name, 'Server has disabled collapse.') | ||||
|                 log('Collapse has stopped.') | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has disabled collapse!', | ||||
|                     { r = 0.98, g = 0.66, b = 0.22 }) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -47,7 +47,7 @@ local function get_top_frame(player) | ||||
| end | ||||
|  | ||||
| local function increment(t, k) | ||||
|     t[k] = {trusted = true, drive = true} | ||||
|     t[k] = { trusted = true, drive = true } | ||||
| end | ||||
|  | ||||
| local function decrement(t, k) | ||||
| @@ -68,11 +68,12 @@ local function get_players(player, frame, all) | ||||
|             insert(tbl, tostring(p.name)) | ||||
|         end | ||||
|     end | ||||
|     insert(tbl, ({'ic.select_player'})) | ||||
|     insert(tbl, ({ 'ic.select_player' })) | ||||
|  | ||||
|     local selected_index = #tbl | ||||
|  | ||||
|     local f = frame.add({type = 'drop-down', name = transfer_player_select_name, items = tbl, selected_index = selected_index}) | ||||
|     local f = frame.add({ type = 'drop-down', name = transfer_player_select_name, items = tbl, | ||||
|         selected_index = selected_index }) | ||||
|     return f | ||||
| end | ||||
|  | ||||
| @@ -128,21 +129,21 @@ end | ||||
| local function draw_add_player(player, frame) | ||||
|     local main_frame = | ||||
|         frame.add( | ||||
|         { | ||||
|             type = 'frame', | ||||
|             name = draw_add_player_frame_name, | ||||
|             caption = ({'ic.add_player'}), | ||||
|             direction = 'vertical' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'frame', | ||||
|                 name = draw_add_player_frame_name, | ||||
|                 caption = ({ 'ic.add_player' }), | ||||
|                 direction = 'vertical' | ||||
|             } | ||||
|         ) | ||||
|     local main_frame_style = main_frame.style | ||||
|     main_frame_style.width = 370 | ||||
|     main_frame_style.use_header_filler = true | ||||
|  | ||||
|     local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'} | ||||
|     local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' } | ||||
|     local inside_frame_style = inside_frame.style | ||||
|     inside_frame_style.padding = 0 | ||||
|     local inside_table = inside_frame.add {type = 'table', column_count = 1} | ||||
|     local inside_table = inside_frame.add { type = 'table', column_count = 1 } | ||||
|     local inside_table_style = inside_table.style | ||||
|     inside_table_style.vertical_spacing = 5 | ||||
|     inside_table_style.top_padding = 10 | ||||
| @@ -153,20 +154,20 @@ local function draw_add_player(player, frame) | ||||
|  | ||||
|     local add_player_frame = get_players(player, main_frame) | ||||
|  | ||||
|     local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'}) | ||||
|     local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' }) | ||||
|  | ||||
|     local left_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local left_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     left_flow.style.horizontal_align = 'left' | ||||
|     left_flow.style.horizontally_stretchable = true | ||||
|  | ||||
|     local close_button = left_flow.add({type = 'button', name = discard_add_player_name, caption = ({'ic.discard'})}) | ||||
|     local close_button = left_flow.add({ type = 'button', name = discard_add_player_name, caption = ({ 'ic.discard' }) }) | ||||
|     close_button.style = 'back_button' ---@class GuiButtonStyle | ||||
|     close_button.style.maximal_width = 100 | ||||
|  | ||||
|     local right_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local right_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     right_flow.style.horizontal_align = 'right' | ||||
|  | ||||
|     local save_button = right_flow.add({type = 'button', name = save_add_player_button_name, caption = ({'ic.save'})}) | ||||
|     local save_button = right_flow.add({ type = 'button', name = save_add_player_button_name, caption = ({ 'ic.save' }) }) | ||||
|     save_button.style = 'confirm_button' ---@class GuiButtonStyle | ||||
|     save_button.style.maximal_width = 100 | ||||
|  | ||||
| @@ -176,21 +177,21 @@ end | ||||
| local function draw_transfer_car(player, frame) | ||||
|     local main_frame = | ||||
|         frame.add( | ||||
|         { | ||||
|             type = 'frame', | ||||
|             name = draw_transfer_car_frame_name, | ||||
|             caption = ({'ic.transfer_car'}), | ||||
|             direction = 'vertical' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'frame', | ||||
|                 name = draw_transfer_car_frame_name, | ||||
|                 caption = ({ 'ic.transfer_car' }), | ||||
|                 direction = 'vertical' | ||||
|             } | ||||
|         ) | ||||
|     local main_frame_style = main_frame.style | ||||
|     main_frame_style.width = 370 | ||||
|     main_frame_style.use_header_filler = true | ||||
|  | ||||
|     local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'} | ||||
|     local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' } | ||||
|     local inside_frame_style = inside_frame.style | ||||
|     inside_frame_style.padding = 0 | ||||
|     local inside_table = inside_frame.add {type = 'table', column_count = 1} | ||||
|     local inside_table = inside_frame.add { type = 'table', column_count = 1 } | ||||
|     local inside_table_style = inside_table.style | ||||
|     inside_table_style.vertical_spacing = 5 | ||||
|     inside_table_style.top_padding = 10 | ||||
| @@ -199,25 +200,25 @@ local function draw_transfer_car(player, frame) | ||||
|     inside_table_style.bottom_padding = 10 | ||||
|     inside_table_style.width = 325 | ||||
|  | ||||
|     local transfer_car_alert_frame = main_frame.add({type = 'label', caption = ({'ic.warning'})}) | ||||
|     transfer_car_alert_frame.style.font_color = {r = 255, g = 0, b = 0} | ||||
|     local transfer_car_alert_frame = main_frame.add({ type = 'label', caption = ({ 'ic.warning' }) }) | ||||
|     transfer_car_alert_frame.style.font_color = { r = 255, g = 0, b = 0 } | ||||
|     transfer_car_alert_frame.style.font = 'heading-1' | ||||
|     local transfer_car_frame = get_players(player, main_frame, true) | ||||
|  | ||||
|     local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'}) | ||||
|     local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' }) | ||||
|  | ||||
|     local left_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local left_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     left_flow.style.horizontal_align = 'left' | ||||
|     left_flow.style.horizontally_stretchable = true | ||||
|  | ||||
|     local close_button = left_flow.add({type = 'button', name = discard_transfer_car_name, caption = ({'ic.discard'})}) | ||||
|     local close_button = left_flow.add({ type = 'button', name = discard_transfer_car_name, caption = ({ 'ic.discard' }) }) | ||||
|     close_button.style = 'back_button' ---@class GuiButtonStyle | ||||
|     close_button.style.maximal_width = 100 | ||||
|  | ||||
|     local right_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local right_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     right_flow.style.horizontal_align = 'right' | ||||
|  | ||||
|     local save_button = right_flow.add({type = 'button', name = save_transfer_car_button_name, caption = ({'ic.save'})}) | ||||
|     local save_button = right_flow.add({ type = 'button', name = save_transfer_car_button_name, caption = ({ 'ic.save' }) }) | ||||
|     save_button.style = 'confirm_button' ---@class GuiButtonStyle | ||||
|     save_button.style.maximal_width = 100 | ||||
|  | ||||
| @@ -227,21 +228,21 @@ end | ||||
| local function draw_destroy_surface_name(frame) | ||||
|     local main_frame = | ||||
|         frame.add( | ||||
|         { | ||||
|             type = 'frame', | ||||
|             name = draw_destroy_surface_frame_name, | ||||
|             caption = ({'ic.destroy_surface'}), | ||||
|             direction = 'vertical' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'frame', | ||||
|                 name = draw_destroy_surface_frame_name, | ||||
|                 caption = ({ 'ic.destroy_surface' }), | ||||
|                 direction = 'vertical' | ||||
|             } | ||||
|         ) | ||||
|     local main_frame_style = main_frame.style | ||||
|     main_frame_style.width = 370 | ||||
|     main_frame_style.use_header_filler = true | ||||
|  | ||||
|     local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'} | ||||
|     local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' } | ||||
|     local inside_frame_style = inside_frame.style | ||||
|     inside_frame_style.padding = 0 | ||||
|     local inside_table = inside_frame.add {type = 'table', column_count = 1} | ||||
|     local inside_table = inside_frame.add { type = 'table', column_count = 1 } | ||||
|     local inside_table_style = inside_table.style | ||||
|     inside_table_style.vertical_spacing = 5 | ||||
|     inside_table_style.top_padding = 10 | ||||
| @@ -250,28 +251,29 @@ local function draw_destroy_surface_name(frame) | ||||
|     inside_table_style.bottom_padding = 10 | ||||
|     inside_table_style.width = 325 | ||||
|  | ||||
|     local destroy_car_frame = main_frame.add({type = 'label', caption = ({'ic.warning'})}) | ||||
|     destroy_car_frame.style.font_color = {r = 255, g = 0, b = 0} | ||||
|     local destroy_car_frame = main_frame.add({ type = 'label', caption = ({ 'ic.warning' }) }) | ||||
|     destroy_car_frame.style.font_color = { r = 255, g = 0, b = 0 } | ||||
|     destroy_car_frame.style.font = 'heading-1' | ||||
|  | ||||
|     local warn_again_frame = main_frame.add({type = 'label', caption = ({'ic.warning_2'})}) | ||||
|     warn_again_frame.style.font_color = {r = 255, g = 0, b = 0} | ||||
|     local warn_again_frame = main_frame.add({ type = 'label', caption = ({ 'ic.warning_2' }) }) | ||||
|     warn_again_frame.style.font_color = { r = 255, g = 0, b = 0 } | ||||
|     warn_again_frame.style.font = 'heading-1' | ||||
|  | ||||
|     local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'}) | ||||
|     local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' }) | ||||
|  | ||||
|     local left_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local left_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     left_flow.style.horizontal_align = 'left' | ||||
|     left_flow.style.horizontally_stretchable = true | ||||
|  | ||||
|     local close_button = left_flow.add({type = 'button', name = discard_destroy_surface_name, caption = ({'ic.discard'})}) | ||||
|     local close_button = left_flow.add({ type = 'button', name = discard_destroy_surface_name, caption = ({ 'ic.discard' }) }) | ||||
|     close_button.style = 'back_button' ---@class GuiButtonStyle | ||||
|     close_button.style.maximal_width = 100 | ||||
|  | ||||
|     local right_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local right_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     right_flow.style.horizontal_align = 'right' | ||||
|  | ||||
|     local save_button = right_flow.add({type = 'button', name = save_destroy_surface_button_name, caption = ({'ic.save'})}) | ||||
|     local save_button = right_flow.add({ type = 'button', name = save_destroy_surface_button_name, | ||||
|         caption = ({ 'ic.save' }) }) | ||||
|     save_button.style = 'confirm_button' ---@class GuiButtonStyle | ||||
|     save_button.style.maximal_width = 100 | ||||
|  | ||||
| @@ -288,55 +290,55 @@ local function draw_players(data) | ||||
|         Gui.set_data(add_player_frame, p) | ||||
|         local t_label = | ||||
|             player_table.add( | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 caption = p | ||||
|             } | ||||
|         ) | ||||
|                 { | ||||
|                     type = 'label', | ||||
|                     caption = p | ||||
|                 } | ||||
|             ) | ||||
|         t_label.style.minimal_width = 75 | ||||
|         t_label.style.horizontal_align = 'center' | ||||
|  | ||||
|         local a_flow = player_table.add {type = 'flow'} | ||||
|         local a_flow = player_table.add { type = 'flow' } | ||||
|         local a_label = | ||||
|             a_flow.add( | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 caption = p_data.trusted and '✔️' or '✖️', | ||||
|                 name = trust_player_name, | ||||
|                 tooltip = ({'ic.allowed_tooltip'}) | ||||
|             } | ||||
|         ) | ||||
|                 { | ||||
|                     type = 'label', | ||||
|                     caption = p_data.trusted and '✔️' or '✖️', | ||||
|                     name = trust_player_name, | ||||
|                     tooltip = ({ 'ic.allowed_tooltip' }) | ||||
|                 } | ||||
|             ) | ||||
|         a_label.style.minimal_width = 75 | ||||
|         a_label.style.horizontal_align = 'center' | ||||
|         a_label.style.font = 'default-large-bold' | ||||
|  | ||||
|         local d_flow = player_table.add {type = 'flow'} | ||||
|         local d_flow = player_table.add { type = 'flow' } | ||||
|         local d_label = | ||||
|             d_flow.add( | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 caption = p_data.drive and '✔️' or '✖️', | ||||
|                 name = drive_player_name, | ||||
|                 tooltip = ({'ic.drive_tooltip'}) | ||||
|             } | ||||
|         ) | ||||
|                 { | ||||
|                     type = 'label', | ||||
|                     caption = p_data.drive and '✔️' or '✖️', | ||||
|                     name = drive_player_name, | ||||
|                     tooltip = ({ 'ic.drive_tooltip' }) | ||||
|                 } | ||||
|             ) | ||||
|         d_label.style.minimal_width = 75 | ||||
|         d_label.style.horizontal_align = 'center' | ||||
|         d_label.style.font = 'default-large-bold' | ||||
|  | ||||
|         local kick_flow = player_table.add {type = 'flow'} | ||||
|         local kick_flow = player_table.add { type = 'flow' } | ||||
|         local kick_player_button = | ||||
|             kick_flow.add( | ||||
|             { | ||||
|                 type = 'button', | ||||
|                 caption = ({'ic.kick'}), | ||||
|                 name = kick_player_name | ||||
|             } | ||||
|         ) | ||||
|                 { | ||||
|                     type = 'button', | ||||
|                     caption = ({ 'ic.kick' }), | ||||
|                     name = kick_player_name | ||||
|                 } | ||||
|             ) | ||||
|         if player.name == t_label.caption then | ||||
|             kick_player_button.enabled = false | ||||
|             a_label.tooltip = ({'ic.not_self'}) | ||||
|             d_label.tooltip = ({'ic.not_self'}) | ||||
|             a_label.tooltip = ({ 'ic.not_self' }) | ||||
|             d_label.tooltip = ({ 'ic.not_self' }) | ||||
|         end | ||||
|         kick_player_button.style.minimal_width = 75 | ||||
|         Gui.set_data(a_label, p) | ||||
| @@ -348,25 +350,25 @@ end | ||||
| local function draw_main_frame(player) | ||||
|     local main_frame = | ||||
|         player.gui.screen.add( | ||||
|         { | ||||
|             type = 'frame', | ||||
|             name = main_frame_name, | ||||
|             caption = ({'ic.car_settings'}), | ||||
|             direction = 'vertical', | ||||
|             style = 'inner_frame_in_outer_frame' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'frame', | ||||
|                 name = main_frame_name, | ||||
|                 caption = ({ 'ic.car_settings' }), | ||||
|                 direction = 'vertical', | ||||
|                 style = 'inner_frame_in_outer_frame' | ||||
|             } | ||||
|         ) | ||||
|  | ||||
|     main_frame.auto_center = true | ||||
|     local main_frame_style = main_frame.style | ||||
|     main_frame_style.width = 450 | ||||
|     main_frame_style.use_header_filler = true | ||||
|  | ||||
|     local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'} | ||||
|     local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' } | ||||
|     local inside_frame_style = inside_frame.style | ||||
|     inside_frame_style.padding = 0 | ||||
|  | ||||
|     local inside_table = inside_frame.add {type = 'table', column_count = 1} | ||||
|     local inside_table = inside_frame.add { type = 'table', column_count = 1 } | ||||
|     local inside_table_style = inside_table.style | ||||
|     inside_table_style.vertical_spacing = 5 | ||||
|     inside_table_style.top_padding = 10 | ||||
| @@ -377,52 +379,54 @@ local function draw_main_frame(player) | ||||
|  | ||||
|     local player_list = Functions.get_trusted_system(player) | ||||
|  | ||||
|     local add_player_frame = inside_table.add({type = 'button', caption = ({'ic.add_player'}), name = add_player_name}) | ||||
|     local transfer_car_frame = inside_table.add({type = 'button', caption = ({'ic.car_settings'}), name = transfer_car_name}) | ||||
|     local destroy_surface_frame = inside_table.add({type = 'button', caption = ({'ic.destroy_surface'}), name = destroy_surface_name}) | ||||
|     local add_player_frame = inside_table.add({ type = 'button', caption = ({ 'ic.add_player' }), name = add_player_name }) | ||||
|     local transfer_car_frame = inside_table.add({ type = 'button', caption = ({ 'ic.car_settings' }), | ||||
|         name = transfer_car_name }) | ||||
|     local destroy_surface_frame = inside_table.add({ type = 'button', caption = ({ 'ic.destroy_surface' }), | ||||
|         name = destroy_surface_name }) | ||||
|     local allow_anyone_to_enter = | ||||
|         inside_table.add( | ||||
|         { | ||||
|             type = 'switch', | ||||
|             name = allow_anyone_to_enter_name, | ||||
|             switch_state = player_list.allow_anyone, | ||||
|             allow_none_state = false, | ||||
|             left_label_caption = ({'ic.allow_anyone'}), | ||||
|             right_label_caption = ({'ic.off'}) | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'switch', | ||||
|                 name = allow_anyone_to_enter_name, | ||||
|                 switch_state = player_list.allow_anyone, | ||||
|                 allow_none_state = false, | ||||
|                 left_label_caption = ({ 'ic.allow_anyone' }), | ||||
|                 right_label_caption = ({ 'ic.off' }) | ||||
|             } | ||||
|         ) | ||||
|     local auto_upgrade = | ||||
|         inside_table.add( | ||||
|         { | ||||
|             type = 'switch', | ||||
|             name = auto_upgrade_name, | ||||
|             switch_state = player_list.auto_upgrade, | ||||
|             allow_none_state = false, | ||||
|             left_label_caption = ({'ic.auto_upgrade'}), | ||||
|             right_label_caption = ({'ic.off'}) | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'switch', | ||||
|                 name = auto_upgrade_name, | ||||
|                 switch_state = player_list.auto_upgrade, | ||||
|                 allow_none_state = false, | ||||
|                 left_label_caption = ({ 'ic.auto_upgrade' }), | ||||
|                 right_label_caption = ({ 'ic.off' }) | ||||
|             } | ||||
|         ) | ||||
|  | ||||
|     local notify_on_driver_change = | ||||
|         inside_table.add( | ||||
|         { | ||||
|             type = 'switch', | ||||
|             name = notify_on_driver_change_name, | ||||
|             switch_state = player_list.notify_on_driver_change, | ||||
|             allow_none_state = false, | ||||
|             left_label_caption = ({'ic.notify_on_driver_change'}), | ||||
|             right_label_caption = ({'ic.off'}) | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'switch', | ||||
|                 name = notify_on_driver_change_name, | ||||
|                 switch_state = player_list.notify_on_driver_change, | ||||
|                 allow_none_state = false, | ||||
|                 left_label_caption = ({ 'ic.notify_on_driver_change' }), | ||||
|                 right_label_caption = ({ 'ic.off' }) | ||||
|             } | ||||
|         ) | ||||
|  | ||||
|     local player_table = | ||||
|         inside_table.add { | ||||
|         type = 'table', | ||||
|         column_count = 4, | ||||
|         draw_horizontal_lines = true, | ||||
|         draw_vertical_lines = true, | ||||
|         vertical_centering = true | ||||
|     } | ||||
|             type = 'table', | ||||
|             column_count = 4, | ||||
|             draw_horizontal_lines = true, | ||||
|             draw_vertical_lines = true, | ||||
|             vertical_centering = true | ||||
|         } | ||||
|     local player_table_style = player_table.style | ||||
|     player_table_style.vertical_spacing = 10 | ||||
|     player_table_style.width = 400 | ||||
| @@ -430,45 +434,45 @@ local function draw_main_frame(player) | ||||
|  | ||||
|     local name_label = | ||||
|         player_table.add( | ||||
|         { | ||||
|             type = 'label', | ||||
|             caption = ({'ic.name'}), | ||||
|             tooltip = '' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 caption = ({ 'ic.name' }), | ||||
|                 tooltip = '' | ||||
|             } | ||||
|         ) | ||||
|     name_label.style.minimal_width = 75 | ||||
|     name_label.style.horizontal_align = 'center' | ||||
|  | ||||
|     local trusted_label = | ||||
|         player_table.add( | ||||
|         { | ||||
|             type = 'label', | ||||
|             caption = ({'ic.allowed'}), | ||||
|             tooltip = '' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 caption = ({ 'ic.allowed' }), | ||||
|                 tooltip = '' | ||||
|             } | ||||
|         ) | ||||
|     trusted_label.style.minimal_width = 75 | ||||
|     trusted_label.style.horizontal_align = 'center' | ||||
|  | ||||
|     local allowed_to_drive = | ||||
|         player_table.add( | ||||
|         { | ||||
|             type = 'label', | ||||
|             caption = ({'ic.drive'}), | ||||
|             tooltip = '' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 caption = ({ 'ic.drive' }), | ||||
|                 tooltip = '' | ||||
|             } | ||||
|         ) | ||||
|     allowed_to_drive.style.minimal_width = 75 | ||||
|     allowed_to_drive.style.horizontal_align = 'center' | ||||
|  | ||||
|     local operations_label = | ||||
|         player_table.add( | ||||
|         { | ||||
|             type = 'label', | ||||
|             caption = ({'ic.operations'}), | ||||
|             tooltip = '' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 caption = ({ 'ic.operations' }), | ||||
|                 tooltip = '' | ||||
|             } | ||||
|         ) | ||||
|     operations_label.style.minimal_width = 75 | ||||
|     operations_label.style.horizontal_align = 'center' | ||||
|  | ||||
| @@ -515,21 +519,21 @@ add_toolbar = function(player, remove) | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     local tooltip = ({'ic.control'}) | ||||
|     local tooltip = ({ 'ic.control' }) | ||||
|     if Gui.get_mod_gui_top_frame() then | ||||
|         local b = | ||||
|             Gui.add_mod_button( | ||||
|             player, | ||||
|             { | ||||
|                 type = 'sprite-button', | ||||
|                 name = main_toolbar_name, | ||||
|                 sprite = 'item/spidertron', | ||||
|                 tooltip = tooltip, | ||||
|                 style = Gui.button_style | ||||
|             } | ||||
|         ) | ||||
|                 player, | ||||
|                 { | ||||
|                     type = 'sprite-button', | ||||
|                     name = main_toolbar_name, | ||||
|                     sprite = 'item/spidertron', | ||||
|                     tooltip = tooltip, | ||||
|                     style = Gui.button_style | ||||
|                 } | ||||
|             ) | ||||
|         if b then | ||||
|             b.style.font_color = {165, 165, 165} | ||||
|             b.style.font_color = { 165, 165, 165 } | ||||
|             b.style.font = 'heading-3' | ||||
|             b.style.minimal_height = 36 | ||||
|             b.style.maximal_height = 36 | ||||
| @@ -539,14 +543,14 @@ add_toolbar = function(player, remove) | ||||
|     else | ||||
|         local button = | ||||
|             player.gui.top.add( | ||||
|             { | ||||
|                 type = 'sprite-button', | ||||
|                 sprite = 'item/spidertron', | ||||
|                 name = main_toolbar_name, | ||||
|                 tooltip = tooltip, | ||||
|                 style = Gui.button_style | ||||
|             } | ||||
|         ) | ||||
|                 { | ||||
|                     type = 'sprite-button', | ||||
|                     sprite = 'item/spidertron', | ||||
|                     name = main_toolbar_name, | ||||
|                     tooltip = tooltip, | ||||
|                     style = Gui.button_style | ||||
|                 } | ||||
|             ) | ||||
|         button.style.minimal_height = 38 | ||||
|         button.style.maximal_height = 38 | ||||
|     end | ||||
| @@ -745,10 +749,13 @@ Gui.on_click( | ||||
|         if frame and frame.valid then | ||||
|             if player_list.notify_on_driver_change == 'right' then | ||||
|                 player_list.notify_on_driver_change = 'left' | ||||
|                 player.print('[IC] You will now be notified whenever someone not trusted tries to drive your car!', Color.success) | ||||
|                 player.print('[IC] You will now be notified whenever someone not trusted tries to drive your car!', | ||||
|                     Color.success) | ||||
|             else | ||||
|                 player_list.notify_on_driver_change = 'right' | ||||
|                 player.print('[IC] No notifications will be sent to you when someone not trusted tries to drive your car.', Color.warning) | ||||
|                 player.print( | ||||
|                 '[IC] No notifications will be sent to you when someone not trusted tries to drive your car.', | ||||
|                     Color.warning) | ||||
|             end | ||||
|  | ||||
|             if player.gui.screen[main_frame_name] then | ||||
| @@ -852,7 +859,8 @@ Gui.on_click( | ||||
|                     player.print('[IC] Please try again.', Color.warning) | ||||
|                 else | ||||
|                     player.print('[IC] You have successfully transferred your car to ' .. name, Color.success) | ||||
|                     player_to_add.print('[IC] You have become the rightfully owner of ' .. player.name .. "'s car!", Color.success) | ||||
|                     player_to_add.print('[IC] You have become the rightfully owner of ' .. player.name .. "'s car!", | ||||
|                         Color.success) | ||||
|                 end | ||||
|  | ||||
|                 remove_main_frame(event.element) | ||||
| @@ -867,16 +875,16 @@ Gui.on_click( | ||||
|  | ||||
| local clear_misc_settings = | ||||
|     Task.register( | ||||
|     function(data) | ||||
|         local player_index = data.player_index | ||||
|         local misc_settings = ICT.get('misc_settings') | ||||
|         if not misc_settings[player_index] then | ||||
|             return | ||||
|         end | ||||
|         function(data) | ||||
|             local player_index = data.player_index | ||||
|             local misc_settings = ICT.get('misc_settings') | ||||
|             if not misc_settings[player_index] then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         misc_settings[player_index] = nil | ||||
|     end | ||||
| ) | ||||
|             misc_settings[player_index] = nil | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| Gui.on_click( | ||||
|     save_destroy_surface_button_name, | ||||
| @@ -905,14 +913,16 @@ Gui.on_click( | ||||
|             } | ||||
|  | ||||
|             player.print('[IC] ARE YOU SURE? This action is irreversible!', Color.warning) | ||||
|             Task.set_timeout_in_ticks(600, clear_misc_settings, {player_index = player.index}) | ||||
|             Task.set_timeout_in_ticks(600, clear_misc_settings, { player_index = player.index }) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if not misc_settings[player.index].final_warning then | ||||
|             misc_settings[player.index].final_warning = true | ||||
|             player.print('[IC] WARNING! WARNING WARNING! Pressing the save button ONE MORE TIME will DELETE your surface. This action is irreversible!', Color.red) | ||||
|             Task.set_timeout_in_ticks(600, clear_misc_settings, {player_index = player.index}) | ||||
|             player.print( | ||||
|             '[IC] WARNING! WARNING WARNING! Pressing the save button ONE MORE TIME will DELETE your surface. This action is irreversible!', | ||||
|                 Color.red) | ||||
|             Task.set_timeout_in_ticks(600, clear_misc_settings, { player_index = player.index }) | ||||
|             return | ||||
|         end | ||||
|  | ||||
| @@ -928,9 +938,13 @@ Gui.on_click( | ||||
|                 local suc, count = Functions.kill_car_but_save_surface(entity) | ||||
|                 if suc then | ||||
|                     game.print('[IC] ' .. player.name .. ' has destroyed their surface!', Color.warning) | ||||
|                     Discord.send_notification_raw(scenario_name, player.name .. ' deleted their vehicle surface at x = ' .. position.x .. ' y = ' .. position.y .. '.') | ||||
|                     Discord.send_notification_raw(scenario_name, | ||||
|                         player.name .. | ||||
|                         ' deleted their vehicle surface at x = ' .. position.x .. ' y = ' .. position.y .. '.') | ||||
|                 else | ||||
|                     player.print('[IC] Entities are still on the surface. Please remove any entities and retry this operation. Found ' .. count .. ' entities!', Color.warning) | ||||
|                     player.print( | ||||
|                     '[IC] Entities are still on the surface. Please remove any entities and retry this operation. Found ' .. | ||||
|                     count .. ' entities!', Color.warning) | ||||
|                 end | ||||
|             end | ||||
|  | ||||
|   | ||||
| @@ -539,7 +539,7 @@ local function refresh_main_frame(data) | ||||
|                                 chestitem.enabled = false | ||||
|                                 chestitem.tooltip = '[Antigrief] You have not grown accustomed to this technology yet.' | ||||
|                             end | ||||
|                             Gui.set_data_parent(volatile_tbl, chestitem, {name = nil, unit_number = unit_number, share = source_chest.share.name}) | ||||
|                             Gui.set_data(chestitem, {name = nil, unit_number = unit_number, share = source_chest.share.name}) | ||||
|                         end | ||||
|                     end | ||||
|                 end | ||||
| @@ -1290,13 +1290,8 @@ Gui.on_click( | ||||
|             Gui.remove_data_recursively(element) | ||||
|             return | ||||
|         end | ||||
|         local parent = player_data.volatile_tbl | ||||
|         if not parent or not parent.valid then | ||||
|             Gui.remove_data_recursively(element) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local data = Gui.get_data_parent(parent, element) | ||||
|         local data = Gui.get_data(element) | ||||
|         if not data then | ||||
|             return | ||||
|         end | ||||
| @@ -1333,10 +1328,10 @@ Gui.on_click( | ||||
|             container.chest.minable = false | ||||
|  | ||||
|             this.linked_gui[event.player.name].updated = false | ||||
|             refresh_main_frame({unit_number = container.unit_number, player = event.player}) | ||||
|             if element and element.valid then | ||||
|                 Gui.remove_data_recursively(element) | ||||
|             end | ||||
|             refresh_main_frame({unit_number = container.unit_number, player = event.player}) | ||||
|         end | ||||
|     end | ||||
| ) | ||||
| @@ -1497,6 +1492,7 @@ function Public.reset() | ||||
|     this.pre_reset_run = false | ||||
| end | ||||
|  | ||||
| Event.on_init(Public.reset) | ||||
| Event.add(defines.events.on_built_entity, on_built_entity) | ||||
| Event.add(defines.events.on_robot_built_entity, built_entity_robot) | ||||
| Event.add(defines.events.on_pre_player_mined_item, on_pre_player_mined_item) | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,6 +1,7 @@ | ||||
| local Event = require 'utils.event' | ||||
| local Global = require 'utils.global' | ||||
| local Gui = require 'utils.gui' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local this = { | ||||
|     renders = {}, | ||||
| @@ -30,11 +31,11 @@ local this = { | ||||
|  | ||||
| local Public = {} | ||||
|  | ||||
| Public.metatable = {__index = Public} | ||||
| Public.metatable = { __index = Public } | ||||
|  | ||||
| Global.register( | ||||
|     this, | ||||
|     function(tbl) | ||||
|     function (tbl) | ||||
|         this = tbl | ||||
|         for _, render in pairs(this.renders) do | ||||
|             setmetatable(render, Public.metatable) | ||||
| @@ -59,7 +60,7 @@ function Public:new_render() | ||||
|         rendering.destroy(self.render_id) | ||||
|     end | ||||
|  | ||||
|     self.render_id = rendering.draw_sprite {target = self.position, sprite = self.sprite, surface = surface} | ||||
|     self.render_id = rendering.draw_sprite { target = self.position, sprite = self.sprite, surface = surface } | ||||
|     return self | ||||
| end | ||||
|  | ||||
| @@ -71,13 +72,13 @@ function Public:new_target() | ||||
|         return | ||||
|     end | ||||
|     local position | ||||
|     local entities = surface.find_entities_filtered {type = this.valid_targets, force = 'player'} | ||||
|     local entities = surface.find_entities_filtered { type = this.valid_targets, force = 'player' } | ||||
|     if entities and #entities > 0 then | ||||
|         position = entities[random(#entities)].position | ||||
|     end | ||||
|  | ||||
|     local chunk = surface.get_random_chunk() | ||||
|     local random_position = {x = (chunk.x + random()) * 32, y = (chunk.y + random()) * 32} | ||||
|     local random_position = { x = (chunk.x + random()) * 32, y = (chunk.y + random()) * 32 } | ||||
|     if not position then | ||||
|         return random_position, random_position | ||||
|     end | ||||
| @@ -91,7 +92,7 @@ function Public:subtr() | ||||
|     if not self.position and self.target_position then | ||||
|         return 0 | ||||
|     end | ||||
|     return {x = self.target_position.x - self.position.x, y = self.target_position.y - self.position.y} | ||||
|     return { x = self.target_position.x - self.position.x, y = self.target_position.y - self.position.y } | ||||
| end | ||||
|  | ||||
| --- Sets the render scale. | ||||
| @@ -101,7 +102,7 @@ function Public:set_render_scalar_size() | ||||
|     end | ||||
|  | ||||
|     rendering.set_y_scale(self.render_id, 3.5) -- 1.5 | ||||
|     rendering.set_x_scale(self.render_id, 7) -- 2 | ||||
|     rendering.set_x_scale(self.render_id, 7)   -- 2 | ||||
|     rendering.set_color( | ||||
|         self.render_id, | ||||
|         { | ||||
| @@ -115,7 +116,7 @@ end | ||||
| --- Gets a random position. | ||||
| ---@return table | ||||
| function Public:random_position() | ||||
|     return {x = self.position.x + (random() - 0.5) * 64, y = self.position.y + (random() - 0.5) * 64} | ||||
|     return { x = self.position.x + (random() - 0.5) * 64, y = self.position.y + (random() - 0.5) * 64 } | ||||
| end | ||||
|  | ||||
| --- Sets a random sprite | ||||
| @@ -150,12 +151,12 @@ function Public:change_position(max_abs, value) | ||||
|     local multiply = sqrt(subtr.x * subtr.x + subtr.y * subtr.y) | ||||
|     if (multiply > max_abs) then | ||||
|         local close = max_abs / multiply | ||||
|         subtr = {x = subtr.x * close, y = subtr.y * close} | ||||
|         subtr = { x = subtr.x * close, y = subtr.y * close } | ||||
|     end | ||||
|     if value then | ||||
|         subtr.y = subtr.y * scalar | ||||
|     end | ||||
|     return {x = self.position.x + subtr.x, y = self.position.y + subtr.y} | ||||
|     return { x = self.position.x + subtr.x, y = self.position.y + subtr.y } | ||||
| end | ||||
|  | ||||
| --- If a render is stuck, give it a new position. | ||||
| @@ -168,7 +169,7 @@ function Public:switch_position() | ||||
|             return | ||||
|         end | ||||
|         local chunk = surface.get_random_chunk() | ||||
|         self.target_position = {x = (chunk.x + math.random()) * 32, y = (chunk.y + math.random()) * 32} | ||||
|         self.target_position = { x = (chunk.x + math.random()) * 32, y = (chunk.y + math.random()) * 32 } | ||||
|     end | ||||
| end | ||||
|  | ||||
| @@ -198,13 +199,13 @@ function Public:render_chart() | ||||
|  | ||||
|     self.chart = | ||||
|         game.forces[self.force].add_chart_tag( | ||||
|         surface, | ||||
|         { | ||||
|             icon = {type = 'virtual', name = 'signal-info'}, | ||||
|             position = self.position, | ||||
|             text = 'Beam' | ||||
|         } | ||||
|     ) | ||||
|             surface, | ||||
|             { | ||||
|                 icon = { type = 'virtual', name = 'signal-info' }, | ||||
|                 position = self.position, | ||||
|                 text = 'Beam' | ||||
|             } | ||||
|         ) | ||||
| end | ||||
|  | ||||
| --- Sets a new position for a render. | ||||
| @@ -233,12 +234,12 @@ function Public:render_fire_damage() | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         surface.create_entity({name = 'fire-flame', position = {x = self.position.x, y = self.position.y + 5}}) | ||||
|         surface.create_entity({ name = 'fire-flame', position = { x = self.position.x, y = self.position.y + 5 } }) | ||||
|         if random(1, 5) == 1 then | ||||
|             surface.create_entity( | ||||
|                 { | ||||
|                     name = 'medium-scorchmark', | ||||
|                     position = {x = self.position.x, y = self.position.y + 5}, | ||||
|                     position = { x = self.position.x, y = self.position.y + 5 }, | ||||
|                     force = 'neutral' | ||||
|                 } | ||||
|             ) | ||||
| @@ -257,13 +258,13 @@ function Public:damage_entities_nearby() | ||||
|         local damage = random(10, 15) | ||||
|         local entities = | ||||
|             surface.find_entities_filtered( | ||||
|             { | ||||
|                 position = self.position, | ||||
|                 radius = 20, | ||||
|                 type = 'simple-entity', | ||||
|                 invert = true | ||||
|             } | ||||
|         ) | ||||
|                 { | ||||
|                     position = self.position, | ||||
|                     radius = 20, | ||||
|                     type = 'simple-entity', | ||||
|                     invert = true | ||||
|                 } | ||||
|             ) | ||||
|         for _, entity in pairs(entities) do | ||||
|             if entity.valid then | ||||
|                 if entity.health then | ||||
| @@ -351,7 +352,7 @@ function Public.new(sprite, surface, ttl, scalar, delayed) | ||||
|         render.delayed = game.tick + delayed | ||||
|         render.ttl = ttl or (game.tick + delayed) + 7200 -- 2 minutes duration | ||||
|     else | ||||
|         render.ttl = ttl or game.tick + 7200 -- 2 minutes duration | ||||
|         render.ttl = ttl or game.tick + 7200             -- 2 minutes duration | ||||
|         render:validate() | ||||
|         if not scalar then | ||||
|             render:set_render_scalar_size() | ||||
| @@ -396,7 +397,7 @@ end | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_tick, | ||||
|     function() | ||||
|     function () | ||||
|         if #this.renders == 0 then | ||||
|             return | ||||
|         end | ||||
| @@ -418,20 +419,13 @@ Event.add( | ||||
|     end | ||||
| ) | ||||
| if _DEBUG then | ||||
|     commands.add_command( | ||||
|         'laser', | ||||
|         'new laser', | ||||
|         function() | ||||
|             local player = game.player | ||||
|             if player and player.valid then | ||||
|                 if not player.admin then | ||||
|                     return | ||||
|                 end | ||||
|  | ||||
|     Commands.new('laser', 'new laser') | ||||
|         :require_admin() | ||||
|         :callback( | ||||
|             function (player) | ||||
|                 Public.new_beam_delayed(player.surface, 222) | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|         ) | ||||
| end | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -1,10 +1,11 @@ | ||||
| local Public = require 'modules.rpg.table' | ||||
| local Utils = require 'utils.core' | ||||
| local Color = require 'utils.color_presets' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local round = math.round | ||||
|  | ||||
| local validate_args = function(data) | ||||
| local validate_args = function (data) | ||||
|     local player = data.player | ||||
|     local target = data.target | ||||
|     local rpg_t = Public.get_value_from_player(target.index) | ||||
| @@ -62,7 +63,7 @@ local validate_args = function(data) | ||||
|     return true | ||||
| end | ||||
|  | ||||
| local print_stats = function(target) | ||||
| local print_stats = function (target) | ||||
|     if not target then | ||||
|         return | ||||
|     end | ||||
| @@ -88,146 +89,84 @@ local print_stats = function(target) | ||||
|     return output | ||||
| end | ||||
|  | ||||
| commands.add_command( | ||||
|     'stats', | ||||
|     'Check what stats a user has!', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
| Commands.new('stats', 'Check what stats a user has!') | ||||
|     :add_parameter('player', false, 'player') | ||||
|     :callback( | ||||
|         function (player, target) | ||||
|             local data = { | ||||
|                 player = player, | ||||
|                 target = target | ||||
|             } | ||||
|  | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|             if validate_args(data) then | ||||
|                 local msg = print_stats(target) | ||||
|                 player.play_sound { path = 'utility/scenario_message', volume_modifier = 1 } | ||||
|                 player.print(msg) | ||||
|             else | ||||
|                 player.print('[Stats] Please type a name of a player who is connected.', Color.warning) | ||||
|                 return false | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         local param = cmd.parameter | ||||
|         if not param then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == '' then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local target = game.players[param] | ||||
|         if not target or not target.valid then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local data = { | ||||
|             player = player, | ||||
|             target = target | ||||
|         } | ||||
|  | ||||
|         if validate_args(data) then | ||||
|             local msg = print_stats(target) | ||||
|             player.play_sound {path = 'utility/scenario_message', volume_modifier = 1} | ||||
|             player.print(msg) | ||||
|         else | ||||
|             player.print('[Stats] Please type a name of a player who is connected.', Color.warning) | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| if _DEBUG then | ||||
|     commands.add_command( | ||||
|         'give_xp', | ||||
|         'DEBUG ONLY - if you are seeing this then this map is running on debug-mode.', | ||||
|         function(cmd) | ||||
|             local p | ||||
|             local player = game.player | ||||
|             local param = tonumber(cmd.parameter) | ||||
|     Commands.new('give_xp', 'Give a player XP!') | ||||
|         :require_admin() | ||||
|         :add_parameter('amount', false, 'number') | ||||
|         :callback( | ||||
|             function (_, amount) | ||||
|                 Public.give_xp(amount) | ||||
|                 game.print('Distributed ' .. amount .. ' of xp.') | ||||
|             end | ||||
|         ) | ||||
|  | ||||
|             if player then | ||||
|                 if player ~= nil then | ||||
|                     p = player.print | ||||
|                     if not player.admin then | ||||
|                         p("[ERROR] You're not admin!", Color.fail) | ||||
|                         return | ||||
|     Commands.new('rpg_debug_module', 'Toggle debug mode for RPG module!') | ||||
|         :require_admin() | ||||
|         :callback( | ||||
|             function () | ||||
|                 Public.toggle_debug() | ||||
|             end | ||||
|         ) | ||||
|  | ||||
|     Commands.new('rpg_debug_aoe_punch', 'Toggle debug mode for RPG module!') | ||||
|         :require_admin() | ||||
|         :callback( | ||||
|             function () | ||||
|                 Public.toggle_debug_aoe_punch() | ||||
|             end | ||||
|         ) | ||||
|  | ||||
|     Commands.new('rpg_cheat_stats', 'Cheat stats for testing purposes!') | ||||
|         :require_admin() | ||||
|         :callback( | ||||
|             function () | ||||
|                 local data = Public.get('rpg_t') | ||||
|                 for k, _ in pairs(data) do | ||||
|                     data[k].dexterity = 999 | ||||
|                     data[k].enable_entity_spawn = true | ||||
|                     data[k].explosive_bullets = true | ||||
|                     data[k].level = 1000 | ||||
|                     data[k].magicka = 999 | ||||
|                     data[k].mana = 50000 | ||||
|                     data[k].mana_max = 50000 | ||||
|                     data[k].debug_mode = true | ||||
|                     data[k].aoe_punch = true | ||||
|                     data[k].stone_path = true | ||||
|                     data[k].strength = 3000 | ||||
|                     data[k].vitality = 3000 | ||||
|                     data[k].xp = 456456 | ||||
|                     local p = game.get_player(k) | ||||
|                     if p and p.valid then | ||||
|                         Public.update_player_stats(p) | ||||
|                     end | ||||
|                     if not param then | ||||
|                         return | ||||
|                     end | ||||
|                     p('Distributed ' .. param .. ' of xp.') | ||||
|                     Public.give_xp(param) | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|     commands.add_command( | ||||
|         'rpg_debug_module', | ||||
|         '', | ||||
|         function() | ||||
|             local player = game.player | ||||
|  | ||||
|             if not (player and player.valid) then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             if not player.admin then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             Public.toggle_debug() | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|     commands.add_command( | ||||
|         'rpg_debug_aoe_punch', | ||||
|         '', | ||||
|         function() | ||||
|             local player = game.player | ||||
|  | ||||
|             if not (player and player.valid) then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             if not player.admin then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             Public.toggle_debug_aoe_punch() | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|     commands.add_command( | ||||
|         'rpg_cheat_stats', | ||||
|         '', | ||||
|         function() | ||||
|             local player = game.player | ||||
|  | ||||
|             if not (player and player.valid) then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             if not player.admin then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             local data = Public.get('rpg_t') | ||||
|             for k, _ in pairs(data) do | ||||
|                 data[k].dexterity = 999 | ||||
|                 data[k].enable_entity_spawn = true | ||||
|                 data[k].explosive_bullets = true | ||||
|                 data[k].level = 1000 | ||||
|                 data[k].magicka = 999 | ||||
|                 data[k].mana = 50000 | ||||
|                 data[k].mana_max = 50000 | ||||
|                 data[k].debug_mode = true | ||||
|                 data[k].aoe_punch = true | ||||
|                 data[k].stone_path = true | ||||
|                 data[k].strength = 3000 | ||||
|                 data[k].vitality = 3000 | ||||
|                 data[k].xp = 456456 | ||||
|                 local p = game.get_player(k) | ||||
|                 if p and p.valid then | ||||
|                     Public.update_player_stats(p) | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|         ) | ||||
| end | ||||
|  | ||||
| local RPG_Interface = { | ||||
|     rpg_reset_player = function(player_name) | ||||
|     rpg_reset_player = function (player_name) | ||||
|         if player_name then | ||||
|             local player = game.get_player(player_name) | ||||
|             if player and player.valid then | ||||
| @@ -239,14 +178,14 @@ local RPG_Interface = { | ||||
|             error('Remote call parameter to RPG rpg_reset_player must be a valid player name and not nil.') | ||||
|         end | ||||
|     end, | ||||
|     give_xp = function(amount) | ||||
|     give_xp = function (amount) | ||||
|         if type(amount) == 'number' then | ||||
|             return Public.give_xp(amount) | ||||
|         else | ||||
|             error('Remote call parameter to RPG give_xp must be number and not nil.') | ||||
|         end | ||||
|     end, | ||||
|     gain_xp = function(player_name, amount) | ||||
|     gain_xp = function (player_name, amount) | ||||
|         if player_name then | ||||
|             local player = game.get_player(player_name) | ||||
|             if player and player.valid and type(amount) == 'number' then | ||||
|   | ||||
| @@ -5,6 +5,7 @@ local Color = require 'utils.color_presets' | ||||
| local SpamProtection = require 'utils.spam_protection' | ||||
| local Event = require 'utils.event' | ||||
| local Gui = require 'utils.gui' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local this = { | ||||
|     data = {}, | ||||
| @@ -14,7 +15,7 @@ local Public = {} | ||||
|  | ||||
| Global.register( | ||||
|     this, | ||||
|     function(tbl) | ||||
|     function (tbl) | ||||
|         this = tbl | ||||
|     end | ||||
| ) | ||||
| @@ -63,7 +64,7 @@ local function add_style(guiIn, styleIn) | ||||
| end | ||||
|  | ||||
| local function adjust_space(guiIn) | ||||
|     add_style(guiIn.add {type = 'line', direction = 'horizontal'}, space) | ||||
|     add_style(guiIn.add { type = 'line', direction = 'horizontal' }, space) | ||||
| end | ||||
|  | ||||
| local function is_valid(obj) | ||||
| @@ -158,19 +159,19 @@ end | ||||
|  | ||||
| local function get_inventory_type(player, inventory_type) | ||||
|     local target_types = { | ||||
|         ['Main'] = function() | ||||
|         ['Main'] = function () | ||||
|             return unpack_inventory(player.get_main_inventory()) | ||||
|         end, | ||||
|         ['Armor'] = function() | ||||
|         ['Armor'] = function () | ||||
|             return unpack_inventory(player.get_inventory(defines.inventory.character_armor)) | ||||
|         end, | ||||
|         ['Guns'] = function() | ||||
|         ['Guns'] = function () | ||||
|             return unpack_inventory(player.get_inventory(defines.inventory.character_guns)) | ||||
|         end, | ||||
|         ['Ammo'] = function() | ||||
|         ['Ammo'] = function () | ||||
|             return unpack_inventory(player.get_inventory(defines.inventory.character_ammo)) | ||||
|         end, | ||||
|         ['Trash'] = function() | ||||
|         ['Trash'] = function () | ||||
|             return unpack_inventory(player.get_inventory(defines.inventory.character_trash)) | ||||
|         end | ||||
|     } | ||||
| @@ -180,7 +181,7 @@ end | ||||
| local function redraw_inventory(gui, source, target, caption, panel_type) | ||||
|     gui.clear() | ||||
|  | ||||
|     local items_table = gui.add({type = 'table', column_count = 11}) | ||||
|     local items_table = gui.add({ type = 'table', column_count = 11 }) | ||||
|     local types = game.item_prototypes | ||||
|  | ||||
|     local screen = source.gui.screen | ||||
| @@ -196,20 +197,20 @@ local function redraw_inventory(gui, source, target, caption, panel_type) | ||||
|         if panel_type[i] and panel_type[i].valid_for_read then | ||||
|             local name = panel_type[i].name | ||||
|             local count = panel_type[i].count | ||||
|             local flow = items_table.add({type = 'flow'}) | ||||
|             local flow = items_table.add({ type = 'flow' }) | ||||
|             flow.style.vertical_align = 'bottom' | ||||
|  | ||||
|             local button = | ||||
|                 flow.add( | ||||
|                 { | ||||
|                     type = 'sprite-button', | ||||
|                     sprite = 'item/' .. name, | ||||
|                     number = count, | ||||
|                     name = name, | ||||
|                     tooltip = types[name].localised_name, | ||||
|                     style = 'slot_button' | ||||
|                 } | ||||
|             ) | ||||
|                     { | ||||
|                         type = 'sprite-button', | ||||
|                         sprite = 'item/' .. name, | ||||
|                         number = count, | ||||
|                         name = name, | ||||
|                         tooltip = types[name].localised_name, | ||||
|                         style = 'slot_button' | ||||
|                     } | ||||
|                 ) | ||||
|             button.enabled = false | ||||
|  | ||||
|             if caption == 'Armor' then | ||||
| @@ -218,15 +219,15 @@ local function redraw_inventory(gui, source, target, caption, panel_type) | ||||
|                     for k, v in pairs(p_armor) do | ||||
|                         local armor_gui = | ||||
|                             flow.add( | ||||
|                             { | ||||
|                                 type = 'sprite-button', | ||||
|                                 sprite = 'item/' .. k, | ||||
|                                 number = v, | ||||
|                                 name = k, | ||||
|                                 tooltip = types[name].localised_name, | ||||
|                                 style = 'slot_button' | ||||
|                             } | ||||
|                         ) | ||||
|                                 { | ||||
|                                     type = 'sprite-button', | ||||
|                                     sprite = 'item/' .. k, | ||||
|                                     number = v, | ||||
|                                     name = k, | ||||
|                                     tooltip = types[name].localised_name, | ||||
|                                     style = 'slot_button' | ||||
|                                 } | ||||
|                             ) | ||||
|                         armor_gui.enabled = false | ||||
|                     end | ||||
|                 end | ||||
| @@ -238,15 +239,15 @@ end | ||||
| local function add_inventory(panel, source, target, caption, panel_type) | ||||
|     local data = get_player_data(source) | ||||
|     data.panel_type = data.panel_type or {} | ||||
|     local pane_name = panel.add({type = 'tab', caption = caption, name = caption}) | ||||
|     local pane_name = panel.add({ type = 'tab', caption = caption, name = caption }) | ||||
|     local scroll_pane = | ||||
|         panel.add { | ||||
|         type = 'scroll-pane', | ||||
|         name = caption .. 'tab', | ||||
|         direction = 'vertical', | ||||
|         vertical_scroll_policy = 'always', | ||||
|         horizontal_scroll_policy = 'never' | ||||
|     } | ||||
|             type = 'scroll-pane', | ||||
|             name = caption .. 'tab', | ||||
|             direction = 'vertical', | ||||
|             vertical_scroll_policy = 'always', | ||||
|             horizontal_scroll_policy = 'never' | ||||
|         } | ||||
|     scroll_pane.style.maximal_height = 200 | ||||
|     scroll_pane.style.horizontally_stretchable = true | ||||
|     scroll_pane.style.minimal_height = 200 | ||||
| @@ -281,13 +282,13 @@ local function open_inventory(source, target) | ||||
|  | ||||
|     local frame = | ||||
|         screen.add( | ||||
|         { | ||||
|             type = 'frame', | ||||
|             caption = 'Inventory', | ||||
|             direction = 'vertical', | ||||
|             name = main_frame_name | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'frame', | ||||
|                 caption = 'Inventory', | ||||
|                 direction = 'vertical', | ||||
|                 name = main_frame_name | ||||
|             } | ||||
|         ) | ||||
|  | ||||
|     if not (frame and frame.valid) then | ||||
|         return | ||||
| @@ -299,7 +300,7 @@ local function open_inventory(source, target) | ||||
|  | ||||
|     adjust_space(frame) | ||||
|  | ||||
|     local panel = frame.add({type = 'tabbed-pane', name = 'tabbed_pane'}) | ||||
|     local panel = frame.add({ type = 'tabbed-pane', name = 'tabbed_pane' }) | ||||
|     panel.selected_tab_index = 1 | ||||
|  | ||||
|     local data = get_player_data(source) | ||||
| @@ -416,42 +417,29 @@ local function update_gui(event) | ||||
|     end | ||||
| end | ||||
|  | ||||
| commands.add_command( | ||||
|     'inventory', | ||||
|     'Opens a players inventory!', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
|  | ||||
|         if this.module_disabled then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if validate_player(player) then | ||||
|             if not cmd.parameter then | ||||
|                 return | ||||
| Commands.new('inventory', 'Open another players inventory') | ||||
|     :add_parameter('player', false, 'player-online') | ||||
|     :callback( | ||||
|         function (player, target) | ||||
|             if this.module_disabled then | ||||
|                 return false | ||||
|             end | ||||
|             local target_player = game.get_player(cmd.parameter) | ||||
|  | ||||
|             if target_player == player and not player.admin then | ||||
|                 return player.print('Cannot open self.', Color.warning) | ||||
|             end | ||||
|             local valid, opened = player_opened(player) | ||||
|             if valid then | ||||
|                 if target_player == opened then | ||||
|                     return player.print('You are already viewing this players inventory.', Color.warning) | ||||
|             if target and target.valid then | ||||
|                 local valid, opened = player_opened(player) | ||||
|                 if valid then | ||||
|                     if target.index == opened then | ||||
|                         player.print('You are already viewing this players inventory.', Color.warning) | ||||
|                         return false | ||||
|                     end | ||||
|                 end | ||||
|             end | ||||
|  | ||||
|             if validate_player(target_player) then | ||||
|                 open_inventory(player, target_player) | ||||
|                 open_inventory(player, target) | ||||
|             else | ||||
|                 player.print('[Inventory] Please type a name of a player who is connected.', Color.warning) | ||||
|             end | ||||
|         else | ||||
|             return | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| function Public.show_inventory(player, target_player) | ||||
|     if not player or not player.valid then | ||||
| @@ -501,7 +489,7 @@ end | ||||
|  | ||||
| Gui.on_custom_close( | ||||
|     main_frame_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not this.data[player.index] then | ||||
|             return | ||||
|   | ||||
| @@ -1,95 +1,80 @@ | ||||
| local Public = require 'modules.wave_defense.table' | ||||
| local Commands = require 'utils.commands' | ||||
| local module_name = '[WD]' | ||||
|  | ||||
| commands.add_command( | ||||
|     'wd_debug_module', | ||||
|     '', | ||||
|     function(cmd) | ||||
|         local p | ||||
|         local player = game.player | ||||
|  | ||||
|         if not player or not player.valid then | ||||
|             p = print | ||||
|         else | ||||
|             p = player.print | ||||
|             if not player.admin then | ||||
|                 return | ||||
| Commands.new('wd_debug_module', 'Usable only for admins - controls wave defense module!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :add_parameter('skip/toggle_es/toggle_es_boss/spawn/next/next_50/next_1500/log_all/debug_health', false, 'string') | ||||
|     :callback( | ||||
|         function (player, action) | ||||
|             if action == 'skip' then | ||||
|                 Public.get('enable_grace_time').enabled = false | ||||
|                 player.print(module_name .. ' grace skipped!') | ||||
|                 return true | ||||
|             end | ||||
|         end | ||||
|  | ||||
|         local param = tostring(cmd.parameter) | ||||
|         if param == 'nil' then | ||||
|             p('[ERROR] Arguments are:\nskip\toggle_es\toggle_es_boss\nspawn\nnext\nnext_50\nnext_1500\nlog_all\ndebug_health') | ||||
|             return | ||||
|         end | ||||
|             if action == 'toggle_es' then | ||||
|                 Public.set_module_status() | ||||
|                 player.print(module_name .. ' ES has been toggled!') | ||||
|                 return true | ||||
|             end | ||||
|  | ||||
|         if param == 'skip' then | ||||
|             Public.get('enable_grace_time').enabled = false | ||||
|             p(module_name .. ' grace skipped!') | ||||
|             return | ||||
|         end | ||||
|             if action == 'toggle_es_boss' then | ||||
|                 Public.set_track_bosses_only() | ||||
|                 player.print(module_name .. ' ES bosses has been toggled!') | ||||
|                 return true | ||||
|             end | ||||
|  | ||||
|         if param == 'toggle_es' then | ||||
|             Public.set_module_status() | ||||
|             p(module_name .. ' ES has been toggled!') | ||||
|             return | ||||
|         end | ||||
|             if action == 'spawn' then | ||||
|                 Public.spawn_unit_group({ true }, true) | ||||
|                 player.print(module_name .. ' wave spawned!') | ||||
|                 return true | ||||
|             end | ||||
|  | ||||
|         if param == 'toggle_es_boss' then | ||||
|             Public.set_track_bosses_only() | ||||
|             p(module_name .. ' ES bosses has been toggled!') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == 'spawn' then | ||||
|             Public.spawn_unit_group({true}, true) | ||||
|             p(module_name .. ' wave spawned!') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == 'next' then | ||||
|             Public.set_next_wave() | ||||
|             Public.spawn_unit_group({true}, true) | ||||
|             p(module_name .. ' wave spawned!') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == 'next_50' then | ||||
|             for _ = 1, 50 do | ||||
|             if action == 'next' then | ||||
|                 Public.set_next_wave() | ||||
|                 Public.spawn_unit_group({ true }, true) | ||||
|                 player.print(module_name .. ' wave spawned!') | ||||
|                 return true | ||||
|             end | ||||
|             Public.spawn_unit_group({true}, true) | ||||
|             p(module_name .. ' wave spawned!') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == 'next_1500' then | ||||
|             for _ = 1, 1500 do | ||||
|                 Public.set_next_wave() | ||||
|             if action == 'next_50' then | ||||
|                 for _ = 1, 50 do | ||||
|                     Public.set_next_wave() | ||||
|                 end | ||||
|                 Public.spawn_unit_group({ true }, true) | ||||
|                 player.print(module_name .. ' wave spawned!') | ||||
|                 return true | ||||
|             end | ||||
|  | ||||
|             if action == 'next_1500' then | ||||
|                 for _ = 1, 1500 do | ||||
|                     Public.set_next_wave() | ||||
|                 end | ||||
|                 Public.spawn_unit_group({ true }, true) | ||||
|                 player.print(module_name .. ' wave spawned!') | ||||
|                 return true | ||||
|             end | ||||
|  | ||||
|             if action == 'log_all' then | ||||
|                 Public.toggle_debug() | ||||
|                 player.print(module_name .. ' debug toggled!') | ||||
|                 return true | ||||
|             end | ||||
|  | ||||
|             if action == 'debug_health' then | ||||
|                 Public.toggle_debug_health() | ||||
|                 local this = Public.get() | ||||
|  | ||||
|                 this.next_wave = 1000 | ||||
|                 this.wave_interval = 200 | ||||
|                 this.wave_enforced = true | ||||
|                 this.debug_only_on_wave_500 = true | ||||
|                 player.print(module_name .. ' debug health toggled!') | ||||
|                 return true | ||||
|             end | ||||
|             Public.spawn_unit_group({true}, true) | ||||
|             p(module_name .. ' wave spawned!') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == 'log_all' then | ||||
|             Public.toggle_debug() | ||||
|             p(module_name .. ' debug toggled!') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == 'debug_health' then | ||||
|             local this = Public.get() | ||||
|  | ||||
|             Public.toggle_debug_health() | ||||
|  | ||||
|             this.next_wave = 1000 | ||||
|             this.wave_interval = 200 | ||||
|             this.wave_enforced = true | ||||
|             this.debug_only_on_wave_500 = true | ||||
|             p(module_name .. ' debug health toggled!') | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -6,6 +6,7 @@ local Task = require 'utils.task' | ||||
| local Server = require 'utils.server' | ||||
| local SpamProtection = require 'utils.spam_protection' | ||||
| local Alert = require 'utils.alert' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local main_frame_name = Gui.uid_name() | ||||
| local save_button_name = Gui.uid_name() | ||||
| @@ -29,33 +30,33 @@ function Public.main_gui(player, text) | ||||
|     end | ||||
|     main_frame = | ||||
|         player.gui.screen.add( | ||||
|         { | ||||
|             type = 'frame', | ||||
|             name = main_frame_name, | ||||
|             caption = 'A stretch is needed.', | ||||
|             direction = 'vertical' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'frame', | ||||
|                 name = main_frame_name, | ||||
|                 caption = 'A stretch is needed.', | ||||
|                 direction = 'vertical' | ||||
|             } | ||||
|         ) | ||||
|     main_frame.auto_center = true | ||||
|     local main_frame_style = main_frame.style | ||||
|     main_frame_style.width = 500 | ||||
|  | ||||
|     local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'} | ||||
|     local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' } | ||||
|     local inside_frame_style = inside_frame.style | ||||
|     inside_frame_style.padding = 0 | ||||
|     local inside_table = inside_frame.add {type = 'table', column_count = 1} | ||||
|     local inside_table = inside_frame.add { type = 'table', column_count = 1 } | ||||
|     local inside_table_style = inside_table.style | ||||
|     inside_table_style.vertical_spacing = 0 | ||||
|  | ||||
|     inside_table.add({type = 'line'}) | ||||
|     inside_table.add({ type = 'line' }) | ||||
|  | ||||
|     local info_main = | ||||
|         inside_table.add( | ||||
|         { | ||||
|             type = 'label', | ||||
|             caption = '[color=yellow]' .. text .. ',[/color]' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 caption = '[color=yellow]' .. text .. ',[/color]' | ||||
|             } | ||||
|         ) | ||||
|     local info_main_style = info_main.style | ||||
|     info_main_style.font = 'default-large-bold' | ||||
|     info_main_style.padding = 0 | ||||
| @@ -63,17 +64,17 @@ function Public.main_gui(player, text) | ||||
|     info_main_style.horizontal_align = 'left' | ||||
|     info_main_style.vertical_align = 'bottom' | ||||
|     info_main_style.single_line = false | ||||
|     info_main_style.font_color = {0.55, 0.55, 0.99} | ||||
|     info_main_style.font_color = { 0.55, 0.55, 0.99 } | ||||
|  | ||||
|     inside_table.add({type = 'line'}) | ||||
|     inside_table.add({ type = 'line' }) | ||||
|  | ||||
|     local info_sub = | ||||
|         inside_table.add( | ||||
|         { | ||||
|             type = 'label', | ||||
|             caption = 'We have played for ' .. Server.format_time(game.ticks_played) .. ' now.\nIf you want to take a quick break,\nplease vote to pause the waves for 5 minutes.' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 caption = 'We have played for ' .. Server.format_time(game.ticks_played) .. ' now.\nIf you want to take a quick break,\nplease vote to pause the waves for 5 minutes.' | ||||
|             } | ||||
|         ) | ||||
|     local info_sub_style = info_sub.style | ||||
|     info_sub_style.font = 'default-game' | ||||
|     info_sub_style.padding = 0 | ||||
| @@ -82,21 +83,21 @@ function Public.main_gui(player, text) | ||||
|     info_sub_style.vertical_align = 'bottom' | ||||
|     info_sub_style.single_line = false | ||||
|  | ||||
|     inside_table.add({type = 'line'}) | ||||
|     inside_table.add({ type = 'line' }) | ||||
|  | ||||
|     local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'}) | ||||
|     local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' }) | ||||
|  | ||||
|     local left_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local left_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     left_flow.style.horizontal_align = 'left' | ||||
|     left_flow.style.horizontally_stretchable = true | ||||
|  | ||||
|     local close_button = left_flow.add({type = 'button', name = discard_button_name, caption = 'I cannot rest!'}) | ||||
|     local close_button = left_flow.add({ type = 'button', name = discard_button_name, caption = 'I cannot rest!' }) | ||||
|     close_button.style = 'back_button' | ||||
|  | ||||
|     local right_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local right_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     right_flow.style.horizontal_align = 'right' | ||||
|  | ||||
|     local save_button = right_flow.add({type = 'button', name = save_button_name, caption = 'I need to stretch'}) | ||||
|     local save_button = right_flow.add({ type = 'button', name = save_button_name, caption = 'I need to stretch' }) | ||||
|     save_button.style = 'confirm_button' | ||||
|  | ||||
|     player.opened = main_frame | ||||
| @@ -128,7 +129,7 @@ local function pause_waves_state(state) | ||||
|  | ||||
|     if state then | ||||
|         if custom_callback then | ||||
|             custom_callback({start = false}) | ||||
|             custom_callback({ start = false }) | ||||
|         end | ||||
|  | ||||
|         local pause_wave_in_ticks = Public.get('pause_wave_in_ticks') | ||||
| @@ -136,16 +137,16 @@ local function pause_waves_state(state) | ||||
|         Public.set('last_pause', game.tick) | ||||
|         Public.set('paused_waves_for', game.tick + pause_wave_in_ticks) | ||||
|         local pause_for = floor(pause_wave_in_ticks / 60 / 60) | ||||
|         local message = ({'wave_defense.pause_waves', pause_for}) | ||||
|         local message = ({ 'wave_defense.pause_waves', pause_for }) | ||||
|         Alert.alert_all_players(30, message, nil, 'achievement/tech-maniac', 0.75) | ||||
|  | ||||
|         local next_wave = Public.get('next_wave') | ||||
|         Public.set('next_wave', next_wave + 18000) | ||||
|     else | ||||
|         if custom_callback then | ||||
|             custom_callback({start = true}) | ||||
|             custom_callback({ start = true }) | ||||
|         end | ||||
|         local message = ({'wave_defense.start_waves'}) | ||||
|         local message = ({ 'wave_defense.start_waves' }) | ||||
|         Alert.alert_all_players(30, message, nil, 'achievement/tech-maniac', 0.75) | ||||
|         Public.normalize_spawn_position() | ||||
|         Public.set('paused', false) | ||||
| @@ -172,7 +173,7 @@ function Public.toggle_pause_wave_without_votes() | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     Public.set('pause_waves', {index = 0}) | ||||
|     Public.set('pause_waves', { index = 0 }) | ||||
|     local pause_wave_in_ticks = Public.get('pause_wave_in_ticks') | ||||
|     pause_waves_state(true) | ||||
|     Task.set_timeout_in_ticks(pause_wave_in_ticks, pause_waves_state_token, false) -- 5 minutes | ||||
| @@ -180,7 +181,7 @@ end | ||||
|  | ||||
| Gui.on_click( | ||||
|     save_button_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local is_spamming = SpamProtection.is_spamming(event.player, nil, 'WD Save Button') | ||||
|         if is_spamming then | ||||
|             return | ||||
| @@ -200,13 +201,13 @@ Gui.on_click( | ||||
|         local divided = total_players / 2 | ||||
|  | ||||
|         if pause_waves.index >= divided then | ||||
|             Public.set('pause_waves', {index = 0}) | ||||
|             Public.set('pause_waves', { index = 0 }) | ||||
|             local players = game.connected_players | ||||
|             for i = 1, #players do | ||||
|                 local p = players[i] | ||||
|                 local screen = p.gui.screen | ||||
|                 local frame = screen[main_frame_name] | ||||
|                 p.surface.play_sound({path = 'utility/new_objective', position = p.position, volume_modifier = 0.75}) | ||||
|                 p.surface.play_sound({ path = 'utility/new_objective', position = p.position, volume_modifier = 0.75 }) | ||||
|  | ||||
|                 if frame and frame.valid then | ||||
|                     Gui.remove_data_recursively(frame) | ||||
| @@ -230,7 +231,7 @@ Gui.on_click( | ||||
|  | ||||
| Gui.on_click( | ||||
|     discard_button_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local is_spamming = SpamProtection.is_spamming(event.player, nil, 'WD Discard Button') | ||||
|         if is_spamming then | ||||
|             return | ||||
| @@ -250,7 +251,7 @@ Gui.on_click( | ||||
|  | ||||
| Event.on_nth_tick( | ||||
|     216000, -- 1 hour | ||||
|     function() | ||||
|     function () | ||||
|         if game.ticks_played < 100 then | ||||
|             return | ||||
|         end | ||||
| @@ -280,51 +281,37 @@ Event.on_nth_tick( | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'wave_defense_pause_waves', | ||||
|     'Usable only for admins - pauses the wave defense waves!', | ||||
|     function() | ||||
|         local player = game.player | ||||
|  | ||||
|         if player and player.valid then | ||||
|             if not player.admin then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
| Commands.new('wave_defense_pause_waves', 'Usable only for admins - pauses the wave defense waves!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             local paused = Public.get('paused') | ||||
|             if paused then | ||||
|                 return | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
|             print('[Wave Defense] ' .. player.name .. ' paused wave defense.') | ||||
|  | ||||
|             Public.toggle_pause_wave() | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'wave_defense_force_pause_waves', | ||||
|     'Usable only for admins - pauses the wave defense waves!', | ||||
|     function() | ||||
|         local player = game.player | ||||
|  | ||||
|         if player and player.valid then | ||||
|             if not player.admin then | ||||
|                 return | ||||
|             end | ||||
|     ) | ||||
|  | ||||
| Commands.new('wave_defense_force_pause_waves', 'Usable only for admins - pauses the wave defense waves!') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             local paused = Public.get('paused') | ||||
|             if paused then | ||||
|                 return | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
|             print('[Wave Defense] ' .. player.name .. ' paused wave defense.') | ||||
|  | ||||
|             Public.toggle_pause_wave_without_votes() | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| --- Toggles if we should show a gui or just pause the waves without votes. | ||||
| ---@param state boolean | ||||
|   | ||||
							
								
								
									
										208
									
								
								utils/alert.lua
									
									
									
									
									
								
							
							
						
						
									
										208
									
								
								utils/alert.lua
									
									
									
									
									
								
							| @@ -1,9 +1,10 @@ | ||||
| local Event = require 'utils.event' | ||||
| local Global = require 'utils.global' | ||||
| local Gui = require 'utils.gui' | ||||
| local Token = require 'utils.token' | ||||
| local Task = require 'utils.task_token' | ||||
| local Color = require 'utils.color_presets' | ||||
| local SpamProtection = require 'utils.spam_protection' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local pairs = pairs | ||||
| local next = next | ||||
| @@ -11,14 +12,14 @@ local next = next | ||||
| local Public = {} | ||||
|  | ||||
| local active_alerts = {} | ||||
| local id_counter = {0} | ||||
| local id_counter = { 0 } | ||||
| local alert_zoom_to_pos = Gui.uid_name() | ||||
|  | ||||
| local on_tick | ||||
|  | ||||
| Global.register( | ||||
|     {active_alerts = active_alerts, id_counter = id_counter}, | ||||
|     function(tbl) | ||||
|     { active_alerts = active_alerts, id_counter = id_counter }, | ||||
|     function (tbl) | ||||
|         active_alerts = tbl.active_alerts | ||||
|         id_counter = tbl.id_counter | ||||
|     end | ||||
| @@ -34,6 +35,41 @@ local close_alert_name = Gui.uid_name() | ||||
| -- own name you can use Public.close_alert(element) | ||||
| Public.close_alert_name = close_alert_name | ||||
|  | ||||
| local delay_print_alert_token = | ||||
|     Task.register( | ||||
|         function (event) | ||||
|             local text = event.text | ||||
|             if not text then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             local ttl = event.ttl | ||||
|             if not ttl then | ||||
|                 ttl = 60 | ||||
|             end | ||||
|  | ||||
|             local sprite = event.sprite | ||||
|             local color = event.color | ||||
|  | ||||
|             Public.alert_all_players(ttl, text, color, sprite, 1) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| Public.set_timeout_in_ticks_alert = function (delay, data) | ||||
|     if not data then | ||||
|         return error('Data was not provided', 2) | ||||
|     end | ||||
|     if type(data) ~= 'table' then | ||||
|         return error("Data must be of type 'table'", 2) | ||||
|     end | ||||
|  | ||||
|     if not delay then | ||||
|         return error('No delay was provided', 2) | ||||
|     end | ||||
|  | ||||
|     Task.set_timeout_in_ticks(delay, delay_print_alert_token, data) | ||||
| end | ||||
|  | ||||
| ---Creates a unique ID for a alert message | ||||
| local function autoincrement() | ||||
|     local id = id_counter[1] + 1 | ||||
| @@ -77,15 +113,15 @@ end | ||||
| ---@param duration number in seconds | ||||
| ---@param sound string sound to play, nil to not play anything | ||||
| local function alert_to(player, duration, sound, volume) | ||||
|     local frame_holder = player.gui.left.add({type = 'flow'}) | ||||
|     local frame_holder = player.gui.left.add({ type = 'flow' }) | ||||
|  | ||||
|     local frame = frame_holder.add({type = 'frame', name = alert_frame_name, direction = 'vertical', style = 'captionless_frame'}) | ||||
|     local frame = frame_holder.add({ type = 'frame', name = alert_frame_name, direction = 'vertical', style = 'captionless_frame' }) | ||||
|     frame.style.width = 300 | ||||
|  | ||||
|     local container = frame.add({type = 'flow', name = alert_container_name, direction = 'horizontal'}) | ||||
|     local container = frame.add({ type = 'flow', name = alert_container_name, direction = 'horizontal' }) | ||||
|     container.style.horizontally_stretchable = true | ||||
|  | ||||
|     local progressbar = frame.add({type = 'progressbar', name = alert_progress_name}) | ||||
|     local progressbar = frame.add({ type = 'progressbar', name = alert_progress_name }) | ||||
|     local style = progressbar.style | ||||
|     style.width = 290 | ||||
|     style.height = 4 | ||||
| @@ -116,7 +152,7 @@ local function alert_to(player, duration, sound, volume) | ||||
|  | ||||
|     if sound then | ||||
|         volume = volume or 0.60 | ||||
|         player.play_sound({path = sound, volume_modifier = volume}) | ||||
|         player.play_sound({ path = sound, volume_modifier = volume }) | ||||
|     end | ||||
|  | ||||
|     return container | ||||
| @@ -173,20 +209,20 @@ local function update_alert(id, frame, tick) | ||||
| end | ||||
|  | ||||
| on_tick = | ||||
|     Token.register( | ||||
|     function(event) | ||||
|         if not next(active_alerts) then | ||||
|             Event.remove_removable_nth_tick(2, on_tick) | ||||
|             return | ||||
|         end | ||||
|     Task.register( | ||||
|         function (event) | ||||
|             if not next(active_alerts) then | ||||
|                 Event.remove_removable_nth_tick(2, on_tick) | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         local tick = event.tick | ||||
|             local tick = event.tick | ||||
|  | ||||
|         for id, frame in pairs(active_alerts) do | ||||
|             update_alert(id, frame, tick) | ||||
|             for id, frame in pairs(active_alerts) do | ||||
|                 update_alert(id, frame, tick) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| ---Message a specific player, template is a callable that receives a LuaGuiElement | ||||
| ---to add contents to and a player as second argument. | ||||
| @@ -239,23 +275,23 @@ function Public.alert_all_players_location(player, message, color, duration) | ||||
|     local length = duration or 15 | ||||
|     Public.alert_all_players_template( | ||||
|         length, | ||||
|         function(container) | ||||
|         function (container) | ||||
|             local sprite = | ||||
|                 container.add { | ||||
|                 type = 'sprite-button', | ||||
|                 name = alert_zoom_to_pos, | ||||
|                 sprite = 'utility/search_icon', | ||||
|                 style = 'slot_button' | ||||
|             } | ||||
|                     type = 'sprite-button', | ||||
|                     name = alert_zoom_to_pos, | ||||
|                     sprite = 'utility/search_icon', | ||||
|                     style = 'slot_button' | ||||
|                 } | ||||
|  | ||||
|             Gui.set_data(sprite, player.position) | ||||
|  | ||||
|             local label = | ||||
|                 container.add { | ||||
|                 type = 'label', | ||||
|                 name = Public.close_alert_name, | ||||
|                 caption = message | ||||
|             } | ||||
|                     type = 'label', | ||||
|                     name = Public.close_alert_name, | ||||
|                     caption = message | ||||
|                 } | ||||
|             local label_style = label.style | ||||
|             label_style.single_line = false | ||||
|             label_style.font_color = color or Color.comfy | ||||
| @@ -272,13 +308,13 @@ function Public.alert_player(player, duration, message, color, sprite, volume) | ||||
|     Public.alert_player_template( | ||||
|         player, | ||||
|         duration, | ||||
|         function(container) | ||||
|         function (container) | ||||
|             container.add { | ||||
|                 type = 'sprite-button', | ||||
|                 sprite = sprite or 'achievement/you-are-doing-it-right', | ||||
|                 style = 'slot_button' | ||||
|             } | ||||
|             local label = container.add({type = 'label', name = close_alert_name, caption = message}) | ||||
|             local label = container.add({ type = 'label', name = close_alert_name, caption = message }) | ||||
|             label.style.single_line = false | ||||
|             label.style.font_color = color or Color.comfy | ||||
|         end, | ||||
| @@ -296,13 +332,13 @@ function Public.alert_player_warning(player, duration, message, color) | ||||
|     Public.alert_player_template( | ||||
|         player, | ||||
|         duration, | ||||
|         function(container) | ||||
|         function (container) | ||||
|             container.add { | ||||
|                 type = 'sprite-button', | ||||
|                 sprite = 'achievement/golem', | ||||
|                 style = 'slot_button' | ||||
|             } | ||||
|             local label = container.add({type = 'label', name = close_alert_name, caption = message}) | ||||
|             local label = container.add({ type = 'label', name = close_alert_name, caption = message }) | ||||
|             label.style.single_line = false | ||||
|             label.style.font_color = color or Color.comfy | ||||
|         end | ||||
| @@ -333,94 +369,28 @@ function Public.alert_all_players(duration, message, color, sprite, volume) | ||||
|     end | ||||
| end | ||||
|  | ||||
| commands.add_command( | ||||
|     'notify_all_players', | ||||
|     'Usable only for admins - sends an alert message to all players!', | ||||
|     function(cmd) | ||||
|         local p | ||||
|         local player = game.player | ||||
|         local param = cmd.parameter | ||||
| Commands.new('notify_all_players', 'Usable only for admins - sends an alert message to all players!') | ||||
|     :add_parameter('message', false, 'string') | ||||
|     :callback( | ||||
|         function (player, message) | ||||
|             local comfy = '[color=blue]' .. player.name .. ':[/color] \n' | ||||
|             message = comfy .. message | ||||
|             Public.alert_all_players_location(player, message) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         if player then | ||||
|             if player ~= nil then | ||||
|                 p = player.print | ||||
|                 if not player.admin then | ||||
|                     p("[ERROR] You're not admin!", Color.fail) | ||||
|                     return | ||||
|                 end | ||||
|                 if not param then | ||||
|                     return p('Valid arguments are: message_to_print') | ||||
|                 end | ||||
| Commands.new('notify_player', 'Usable only for admins - sends an alert message to a player!') | ||||
|     :add_parameter('player', false, 'player-online') | ||||
|     :add_parameter('message', false, 'string') | ||||
|     :callback( | ||||
|         function (player, target_player, message) | ||||
|             if target_player then | ||||
|                 local comfy = '[color=blue]' .. player.name .. ':[/color] \n' | ||||
|                 local message = comfy .. param | ||||
|                 Public.alert_all_players_location(player, message) | ||||
|             end | ||||
|         else | ||||
|             p = log | ||||
|             if not param then | ||||
|                 return p('Valid arguments are: message_to_print') | ||||
|             end | ||||
|             local comfy = '[color=blue]Server:[/color] \n' | ||||
|             local message = comfy .. param | ||||
|             p(param) | ||||
|             Public.alert_all_players(15, message) | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'notify_player', | ||||
|     'Usable only for admins - sends an alert message to a player!', | ||||
|     function(cmd) | ||||
|         local p | ||||
|         local player = game.player | ||||
|         local param = cmd.parameter | ||||
|  | ||||
|         if player then | ||||
|             if player ~= nil then | ||||
|                 p = player.print | ||||
|                 if not player.admin then | ||||
|                     p("[ERROR] You're not admin!", Color.fail) | ||||
|                     return | ||||
|                 end | ||||
|  | ||||
|                 local t_player | ||||
|                 local t_message | ||||
|                 local target_player | ||||
|                 local str = '' | ||||
|  | ||||
|                 if not param then | ||||
|                     return p('[ERROR] Valid arguments are:\nplayer = player,\nmessage = message', Color.fail) | ||||
|                 end | ||||
|  | ||||
|                 local t = {} | ||||
|                 for i in string.gmatch(param, '%S+') do | ||||
|                     table.insert(t, i) | ||||
|                 end | ||||
|  | ||||
|                 t_player = t[1] | ||||
|  | ||||
|                 for i = 2, #t do | ||||
|                     str = str .. t[i] .. ' ' | ||||
|                     t_message = str | ||||
|                 end | ||||
|  | ||||
|                 if game.players[t_player] then | ||||
|                     target_player = game.players[t_player] | ||||
|                 else | ||||
|                     return p('[ERROR] No player was provided', Color.fail) | ||||
|                 end | ||||
|  | ||||
|                 if t_message then | ||||
|                     local comfy = '[color=blue]' .. player.name .. ':[/color] \n' | ||||
|                     local message = comfy .. t_message | ||||
|                     Public.alert_player_warning(target_player, 15, message) | ||||
|                 else | ||||
|                     p('No message was provided', Color.fail) | ||||
|                 end | ||||
|                 message = comfy .. message | ||||
|                 Public.alert_player_warning(target_player, 15, message) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -1,3 +1,552 @@ | ||||
| require 'utils.commands.trust_system' | ||||
| require 'utils.commands.misc' | ||||
| require 'utils.commands.where' | ||||
| ---@diagnostic disable: deprecated | ||||
| --luacheck: ignore 561 | ||||
| local Global = require 'utils.global' | ||||
| local Core = require 'utils.core' | ||||
| local Session = require 'utils.datastore.session_data' | ||||
| local Supporters = require 'utils.datastore.supporters' | ||||
| local Task = require 'utils.task_token' | ||||
| local Server = require 'utils.server' | ||||
|  | ||||
| ---@class CommandData | ||||
| ---@field name string | ||||
| ---@field help string | ||||
| ---@field aliases table | ||||
| ---@field parameters table | ||||
| ---@field parameters_count number | ||||
| ---@field parameters_required number | ||||
| ---@field check_server boolean | ||||
| ---@field check_backend boolean | ||||
| ---@field check_admin boolean | ||||
| ---@field check_supporter boolean | ||||
| ---@field check_trusted boolean | ||||
| ---@field check_playtime number | ||||
| ---@field callback function | ||||
| ---@field validate_self boolean | ||||
| ---@field validated_command boolean | ||||
| ---@field validate_activated boolean | ||||
| ---@field command_activated boolean | ||||
|  | ||||
| local this = { | ||||
|     commands = {} | ||||
| } | ||||
| local trace = debug.traceback | ||||
|  | ||||
| local output = { | ||||
|     backend_is_required = 'No backend is currently available. Please try again later.', | ||||
|     server_is_required = 'This command requires to be run from the server.', | ||||
|     admin_is_required = 'This command requires admin permissions to run.', | ||||
|     supporter_is_required = 'This command requires supporter permissions to run.', | ||||
|     trusted_is_required = 'This command requires trusted permissions to run.', | ||||
|     playtime_is_required = 'This command requires a minimum playtime to run.', | ||||
|     param_is_required = 'This command requires a parameter to run.', | ||||
|     command_failed = 'Command failed to run.', | ||||
|     command_success = 'Command ran successfully.', | ||||
|     command_needs_validation = | ||||
|     'This command requires validation to run. Please re-run the command if you wish to proceed.', | ||||
|     command_needs_custom_validation = | ||||
|     'This command requires validation to run. %s - please re-run the command if you wish to proceed.', | ||||
|     command_is_active = 'This command is already active.', | ||||
|     command_is_inactive = 'This command is already inactive.' | ||||
| } | ||||
|  | ||||
| local check_boolean = { | ||||
|     ['true'] = true, | ||||
|     ['false'] = true | ||||
| } | ||||
|  | ||||
| ---@class MetaCommand | ||||
| local Public = {} | ||||
|  | ||||
| Public.metatable = { __index = Public } | ||||
|  | ||||
| Global.register( | ||||
|     this, | ||||
|     function (tbl) | ||||
|         this = tbl | ||||
|         for _, command in pairs(this.commands) do | ||||
|             setmetatable(command, Public.metatable) | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| local function conv(v) | ||||
|     if tonumber(v) then | ||||
|         return tonumber(v) | ||||
|     end | ||||
|  | ||||
|     return v | ||||
| end | ||||
|  | ||||
| --- Handles errors. | ||||
| ---@param message string | ||||
| ---@param notify_sound string | ||||
| local function handle_error(message, notify_sound) | ||||
|     message = message or '' | ||||
|     Core.output_message('Command failed: ' .. message, 'warning') | ||||
|     if notify_sound then | ||||
|         notify_sound = notify_sound or 'utility/wire_pickup' | ||||
|         if game.player then | ||||
|             game.player.play_sound { path = notify_sound } | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| --- Handles internal errors. | ||||
| ---@param has_run boolean | ||||
| ---@param name string | ||||
| ---@param message string | ||||
| ---@return boolean | ||||
| local function internal_error(has_run, name, message) | ||||
|     if not has_run then | ||||
|         handle_error('Action has been logged!', 'utility/cannot_build') | ||||
|         if type(message) == 'string' then | ||||
|             Server.output_data('[ERROR] Command failed to run: ' .. name .. ' - ' .. message) | ||||
|         else | ||||
|             Server.output_data('[ERROR] Command failed to run: ' .. name) | ||||
|         end | ||||
|     end | ||||
|     return not has_run | ||||
| end | ||||
|  | ||||
| ---@param event EventData.on_console_command | ||||
| local function execute(event) | ||||
|     local command_data = this.commands[event.name] --[[@as CommandData]] | ||||
|  | ||||
|     local player | ||||
|     if event.player_index and event.player_index > 0 then | ||||
|         player = game.get_player(event.player_index) | ||||
|     else | ||||
|         player = { | ||||
|             name = 'Server', | ||||
|             position = { x = 0, y = 0 }, | ||||
|             surface = game.get_surface('nauvis'), | ||||
|             force = game.forces.player, | ||||
|             print = Server.output_data | ||||
|         } | ||||
|     end | ||||
|  | ||||
|     local is_server = event.player_index == nil | ||||
|  | ||||
|     local function reject(error_message) | ||||
|         error_message = error_message or '' | ||||
|         command_data.validated_command = false | ||||
|         return handle_error(error_message, 'utility/cannot_build') | ||||
|     end | ||||
|  | ||||
|     -- Check if player and return | ||||
|     local check_server = command_data.check_server or false | ||||
|     if (check_server and not is_server) and player and player.valid then | ||||
|         reject(output.server_is_required) | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     -- Check if player and return | ||||
|     local check_backend = command_data.check_backend or false | ||||
|     if (check_backend and not is_server) and event.player_index then | ||||
|         if not Server.get_current_time() then | ||||
|             reject(output.backend_is_required) | ||||
|             return | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     -- Check if the player is an admin and if the command requires it | ||||
|     local check_admin = command_data.check_admin or false | ||||
|     if (check_admin and not is_server) and player and not player.admin then | ||||
|         reject(output.admin_is_required) | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     -- Check if the player is trusted and if the command requires it | ||||
|     local check_trusted = command_data.check_trusted or false | ||||
|     if (check_trusted and not is_server) and Core.validate_player(player) then | ||||
|         local is_trusted = Session.get_trusted_player(player) | ||||
|         if not is_trusted then | ||||
|             reject(output.trusted_is_required) | ||||
|             return | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     -- Check if the player is a supporter and if the command requires it | ||||
|     local check_supporter = command_data.check_supporter or false | ||||
|     if (check_supporter and not is_server) and Core.validate_player(player) then | ||||
|         local is_supporter = Supporters.is_supporter(player.name) | ||||
|         if not is_supporter then | ||||
|             reject(output.supporter_is_required) | ||||
|             return | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     -- Check if the player has the required playtime and if the command requires it | ||||
|     local check_playtime = command_data.check_playtime or false | ||||
|     if (check_playtime and not is_server) and Core.validate_player(player) then | ||||
|         local playtime = Session.get_session_player(player) | ||||
|         if not playtime then | ||||
|             reject(output.trusted_is_required) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if playtime < check_playtime then | ||||
|             reject(output.playtime_is_required) | ||||
|             return | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     -- Check for parameters | ||||
|     if command_data.parameters_required > 0 and not event.parameter then | ||||
|         reject(output.param_is_required) | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     -- Check if the command requires the player to validate the command | ||||
|     local validate_self = command_data.validate_self or false | ||||
|     if validate_self and not command_data.validated_command then | ||||
|         command_data.validated_command = true | ||||
|         if command_data.custom_message then | ||||
|             handle_error(string.format(output.command_needs_custom_validation, command_data.custom_message), | ||||
|                 'utility/cannot_build') | ||||
|         else | ||||
|             handle_error(output.command_needs_validation, 'utility/cannot_build') | ||||
|         end | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     -- Extract quoted arguments | ||||
|     local input_text = event.parameter or '' | ||||
|     local quoted_segments = {} | ||||
|  | ||||
|     local processed_input = | ||||
|         input_text:gsub( | ||||
|             '"([^"]-)"', | ||||
|             function (segment) | ||||
|                 local no_spaces_segment = segment:gsub('%s', '%%s') | ||||
|                 quoted_segments[no_spaces_segment] = segment | ||||
|                 return ' ' .. no_spaces_segment .. ' ' | ||||
|             end | ||||
|         ) | ||||
|  | ||||
|     -- Extract unquoted arguments | ||||
|     local parameters = {} | ||||
|     local current_index = 0 | ||||
|     local parameter_count = 0 | ||||
|  | ||||
|     for word in processed_input:gmatch('%S+') do | ||||
|         parameter_count = parameter_count + 1 | ||||
|         local quoted_word = quoted_segments[word] | ||||
|         local formatted_word = quoted_word and ('"' .. quoted_word .. '"') or word | ||||
|  | ||||
|         if parameter_count > command_data.parameters_count then | ||||
|             parameters[current_index] = parameters[current_index] .. ' ' .. formatted_word | ||||
|         else | ||||
|             current_index = current_index + 1 | ||||
|             parameters[current_index] = formatted_word | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     -- Check the param count | ||||
|     local parameters_count = #parameters | ||||
|     if parameters_count < command_data.parameters_required then | ||||
|         reject(output.param_is_required) | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     -- Parse the arguments | ||||
|     local index = 1 | ||||
|     local handled_parameters = {} | ||||
|     for _, param_data in pairs(command_data.parameters) do | ||||
|         if param_data.as_type then | ||||
|             local param = conv(parameters[index]) | ||||
|             if param_data.as_type == 'player' and param ~= nil then | ||||
|                 local player_name = param | ||||
|                 if type(player_name) ~= 'string' then | ||||
|                     return reject('Inputted value is not of type string. Valid values are: "string"') | ||||
|                 end | ||||
|                 local player_data = game.get_player(player_name) --[[@type LuaPlayer]] | ||||
|                 if not player_data then | ||||
|                     return reject('Player was not found.') | ||||
|                 end | ||||
|                 handled_parameters[index] = player_data | ||||
|                 index = index + 1 | ||||
|             end | ||||
|             if param_data.as_type == 'player-online' and param ~= nil then | ||||
|                 local player_name = param | ||||
|                 if type(player_name) ~= 'string' then | ||||
|                     return reject('Inputted value is not of type string. Valid values are: "string"') | ||||
|                 end | ||||
|                 local player_data = game.get_player(player_name) --[[@type LuaPlayer]] | ||||
|                 if not player_data or not player_data.valid then | ||||
|                     return reject('Player was not found.') | ||||
|                 end | ||||
|                 if not player_data.connected then | ||||
|                     return reject('Player is not online.') | ||||
|                 end | ||||
|                 handled_parameters[index] = player_data | ||||
|                 index = index + 1 | ||||
|             end | ||||
|             if param_data.as_type == 'player-admin' and param ~= nil then | ||||
|                 local player_name = param | ||||
|                 if type(player_name) ~= 'string' then | ||||
|                     return reject('Inputted value is not of type string. Valid values are: "string"') | ||||
|                 end | ||||
|                 local player_data = game.get_player(player_name) --[[@type LuaPlayer]] | ||||
|                 if not player_data or not player_data.valid then | ||||
|                     return reject('Player was not found.') | ||||
|                 end | ||||
|                 if not player_data.admin then | ||||
|                     return reject('Player is not an admin.') | ||||
|                 end | ||||
|                 handled_parameters[index] = player_data | ||||
|                 index = index + 1 | ||||
|             end | ||||
|             if param_data.as_type == 'server' and param ~= nil then | ||||
|                 local player_name = param | ||||
|                 if type(player_name) ~= 'string' then | ||||
|                     return reject('Inputted value is not of type string. Valid values are: "string"') | ||||
|                 end | ||||
|                 local player_data = game.get_player(player_name) --[[@type LuaPlayer]] | ||||
|                 if player_data and player_data.valid then | ||||
|                     return reject('Not running from server.') | ||||
|                 end | ||||
|                 handled_parameters[index] = player_data | ||||
|                 index = index + 1 | ||||
|             end | ||||
|             if (param_data.as_type == 'number' or param_data.as_type == 'integer') and param ~= nil then | ||||
|                 local num = tonumber(param) | ||||
|                 if not num then | ||||
|                     return reject('Inputted value is not of type number. Valid values are: 1, 2, 3, etc.') | ||||
|                 end | ||||
|                 handled_parameters[index] = num | ||||
|                 index = index + 1 | ||||
|             end | ||||
|             if param_data.as_type == 'string' and param ~= nil then | ||||
|                 if type(param) ~= 'string' then | ||||
|                     return reject('Inputted value is not of type string. Valid values are: "string"') | ||||
|                 end | ||||
|  | ||||
|                 handled_parameters[index] = param | ||||
|                 index = index + 1 | ||||
|             end | ||||
|             if param_data.as_type == 'boolean' and param ~= nil then | ||||
|                 if not check_boolean[param] then | ||||
|                     return reject('Inputted value is not of type boolean. Valid values are: true, false.') | ||||
|                 end | ||||
|  | ||||
|                 if command_data.command_activated and param == 'true' then | ||||
|                     return handle_error(output.command_is_active, 'utility/cannot_build') | ||||
|                 end | ||||
|  | ||||
|                 if not command_data.command_activated and param == 'false' then | ||||
|                     return handle_error(output.command_is_inactive, 'utility/cannot_build') | ||||
|                 end | ||||
|  | ||||
|                 handled_parameters[index] = param | ||||
|                 index = index + 1 | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     -- Run the command callback if everything is validated | ||||
|     handled_parameters[#handled_parameters + 1] = input_text | ||||
|     local callback = Task.get(command_data.callback) | ||||
|     local success, err = pcall(callback, player, unpack(handled_parameters)) | ||||
|     if internal_error(success, command_data.name, err) then | ||||
|         return reject(output.command_failed) | ||||
|     end | ||||
|  | ||||
|     -- Check if the command can only be run once | ||||
|     local validate_activated = command_data.validate_activated or false | ||||
|     if validate_activated then | ||||
|         if not command_data.command_activated then | ||||
|             command_data.command_activated = true | ||||
|         else | ||||
|             command_data.command_activated = false | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     command_data.validated_command = false | ||||
|  | ||||
|     if err ~= nil then | ||||
|         if type(err) == 'boolean' then | ||||
|             if err == false then | ||||
|                 Core.output_message(output.command_failed, 'warning') | ||||
|             else | ||||
|                 Core.output_message(output.command_success, 'success') | ||||
|             end | ||||
|         else | ||||
|             Core.output_message(err) | ||||
|         end | ||||
|     else | ||||
|         Core.output_message(output.command_success, 'success') | ||||
|     end | ||||
| end | ||||
|  | ||||
| --- Creates a new command. | ||||
| ---@param name string | ||||
| ---@param help string | ||||
| ---@return MetaCommand | ||||
| function Public.new(name, help) | ||||
|     if this.commands[name] then | ||||
|         error('Command already exists: ' .. name, 2) | ||||
|     end | ||||
|  | ||||
|     local command = | ||||
|         setmetatable( | ||||
|             { | ||||
|                 name = name, | ||||
|                 help = help, | ||||
|                 aliases = {}, | ||||
|                 parameters = {}, | ||||
|                 parameters_count = 0, | ||||
|                 parameters_required = 0, | ||||
|                 check_admin = false, | ||||
|                 check_server = false, | ||||
|                 check_backend = false, | ||||
|                 check_supporter = false, | ||||
|                 check_trusted = false, | ||||
|                 check_playtime = false, | ||||
|                 validate_self = false, | ||||
|                 validated_command = false | ||||
|             }, | ||||
|             Public.metatable | ||||
|         ) | ||||
|  | ||||
|     this.commands[name] = command | ||||
|  | ||||
|     return command | ||||
| end | ||||
|  | ||||
| --- Requires the player to validate the command before running it. | ||||
| ---@param custom_message? string | ||||
| ---@return MetaCommand | ||||
| function Public:require_validation(custom_message) | ||||
|     self.validate_self = true | ||||
|     if custom_message then | ||||
|         self.custom_message = custom_message | ||||
|     end | ||||
|  | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Requires the player to validate the command before running it. | ||||
| ---@return MetaCommand | ||||
| function Public:is_activated() | ||||
|     self.validate_activated = true | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Requires the player to be an admin to run the command. | ||||
| ---@return MetaCommand | ||||
| function Public:require_admin() | ||||
|     self.check_admin = true | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Requires that the command is not run from a player. | ||||
| ---@return MetaCommand | ||||
| function Public:require_server() | ||||
|     self.check_server = true | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Requires that the server is connected to a backend | ||||
| ---@return MetaCommand | ||||
| function Public:require_backend() | ||||
|     self.check_backend = true | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Requires the player to be a supporter to run the command. | ||||
| ---@return MetaCommand | ||||
| function Public:require_supporter() | ||||
|     self.check_supporter = true | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Requires the player to be trusted to run the command. | ||||
| ---@return MetaCommand | ||||
| function Public:require_trusted() | ||||
|     self.check_trusted = true | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Requires the player to have a minimum playtime to run the command. | ||||
| ---@param playtime integer|number | ||||
| ---@return MetaCommand | ||||
| function Public:require_playtime(playtime) | ||||
|     self.check_playtime = playtime or nil | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Adds a parameter to the command. | ||||
| ---@param name string | ||||
| ---@param optional boolean | ||||
| ---@param as_type? type|string | ||||
| ---@return MetaCommand | ||||
| function Public:add_parameter(name, optional, as_type) | ||||
|     if self.parameters[name] then | ||||
|         error('Parameter: ' .. name .. ' already exists for command: ' .. self.name, 2) | ||||
|     end | ||||
|  | ||||
|     self.parameters[name] = { optional = optional, as_type = as_type } | ||||
|     self.parameters_count = self.parameters_count + 1 | ||||
|  | ||||
|     if not optional then | ||||
|         self.parameters_required = self.parameters_required + 1 | ||||
|     end | ||||
|  | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Sets the command as default if marking paramaters as optional. | ||||
| ---@param defaults any | ||||
| ---@return MetaCommand | ||||
| function Public:set_default(defaults) | ||||
|     for name, value in pairs(defaults) do | ||||
|         if self.parameters[name] then | ||||
|             self.parameters[name].default = value | ||||
|         end | ||||
|     end | ||||
|     return self | ||||
| end | ||||
|  | ||||
| --- Registers the command to the game. Will return the player/server and the args as separate arguments. | ||||
| ---@param func function | ||||
| function Public:callback(func) | ||||
|     -- Generates a description to be used | ||||
|     local description = '' | ||||
|     for param_name, param_details in pairs(self.parameters) do | ||||
|         if param_details.optional then | ||||
|             description = string.format('%s [%s]', description, param_name) | ||||
|         else | ||||
|             description = string.format('%s <%s>', description, param_name) | ||||
|         end | ||||
|     end | ||||
|     self.description = description | ||||
|  | ||||
|     -- If command fails to run, notify the player/server | ||||
|     local function command_error(err) | ||||
|         internal_error(false, self.name, trace(err)) | ||||
|     end | ||||
|  | ||||
|     -- Registers the command as a token | ||||
|     local id = Task.register(func) | ||||
|     self.callback = id | ||||
|  | ||||
|     -- Callback | ||||
|     local function command_callback(event) | ||||
|         event.name = self.name | ||||
|         xpcall(execute, command_error, event) | ||||
|     end | ||||
|  | ||||
|     -- Lastly, adds the command to the game | ||||
|     local help = description .. ' - ' .. self.help | ||||
|     commands.add_command(self.name, help, command_callback) | ||||
|  | ||||
|     -- Adds any aliases if any | ||||
|     for _, alias in pairs(self.aliases) do | ||||
|         if not commands.commands[alias] and not commands.game_commands[alias] then | ||||
|             commands.add_command(alias, help, command_callback) | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| ---@diagnostic disable: deprecated | ||||
| local Session = require 'utils.datastore.session_data' | ||||
| local Modifiers = require 'utils.player_modifiers' | ||||
| local Server = require 'utils.server' | ||||
| @@ -8,6 +9,7 @@ local BottomFrame = require 'utils.gui.bottom_frame' | ||||
| local Gui = require 'utils.gui' | ||||
| local SpamProtection = require 'utils.spam_protection' | ||||
| local Discord = require 'utils.discord_handler' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local this = { | ||||
|     players = {}, | ||||
| @@ -16,7 +18,7 @@ local this = { | ||||
|  | ||||
| Global.register( | ||||
|     this, | ||||
|     function(t) | ||||
|     function (t) | ||||
|         this = t | ||||
|     end | ||||
| ) | ||||
| @@ -25,352 +27,254 @@ local Public = {} | ||||
|  | ||||
| local clear_corpse_button_name = Gui.uid_name() | ||||
|  | ||||
| commands.add_command( | ||||
|     'spaghetti', | ||||
|     'Does spaghett.', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
|         local param = tostring(cmd.parameter) | ||||
|         local force = game.forces['player'] | ||||
| Commands.new('playtime', 'Fetches a player total playtime or nil.') | ||||
|     :require_backend() | ||||
|     :add_parameter('target', false, 'string') | ||||
|     :callback( | ||||
|         function (player, target) | ||||
|             Session.get_and_print_to_player(player, target) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         if not (player and player.valid) then | ||||
|             return | ||||
|         end | ||||
|         local p = player.print | ||||
|         if not player.admin then | ||||
|             p("[ERROR] You're not admin!", Color.fail) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == nil then | ||||
|             player.print('[ERROR] Arguments are true/false', Color.yellow) | ||||
|             return | ||||
| Commands.new('refresh', 'Reloads game script') | ||||
|     :require_admin() | ||||
|     :callback( | ||||
|         function () | ||||
|             game.print('Reloading game script...', Color.warning) | ||||
|             Server.to_discord_bold('Reloading game script...') | ||||
|             game.reload_script() | ||||
|         end | ||||
|         if param == 'true' then | ||||
|             if not this.spaghetti_are_you_sure then | ||||
|                 this.spaghetti_are_you_sure = true | ||||
|                 player.print('Spaghetti is not enabled, run this command again to enable spaghett', Color.yellow) | ||||
|                 return | ||||
|             end | ||||
|             if this.spaghetti_enabled then | ||||
|                 player.print('Spaghetti is already enabled.', Color.yellow) | ||||
|                 return | ||||
|             end | ||||
|             game.print('The world has been spaghettified!', Color.success) | ||||
|             force.technologies['logistic-system'].enabled = false | ||||
|             force.technologies['construction-robotics'].enabled = false | ||||
|             force.technologies['logistic-robotics'].enabled = false | ||||
|             force.technologies['robotics'].enabled = false | ||||
|             force.technologies['personal-roboport-equipment'].enabled = false | ||||
|             force.technologies['personal-roboport-mk2-equipment'].enabled = false | ||||
|             force.technologies['character-logistic-trash-slots-1'].enabled = false | ||||
|             force.technologies['character-logistic-trash-slots-2'].enabled = false | ||||
|             force.technologies['auto-character-logistic-trash-slots'].enabled = false | ||||
|             force.technologies['worker-robots-storage-1'].enabled = false | ||||
|             force.technologies['worker-robots-storage-2'].enabled = false | ||||
|             force.technologies['worker-robots-storage-3'].enabled = false | ||||
|             force.technologies['character-logistic-slots-1'].enabled = false | ||||
|             force.technologies['character-logistic-slots-2'].enabled = false | ||||
|             force.technologies['character-logistic-slots-3'].enabled = false | ||||
|             force.technologies['character-logistic-slots-4'].enabled = false | ||||
|             force.technologies['character-logistic-slots-5'].enabled = false | ||||
|             force.technologies['character-logistic-slots-6'].enabled = false | ||||
|             force.technologies['worker-robots-speed-1'].enabled = false | ||||
|             force.technologies['worker-robots-speed-2'].enabled = false | ||||
|             force.technologies['worker-robots-speed-3'].enabled = false | ||||
|             force.technologies['worker-robots-speed-4'].enabled = false | ||||
|             force.technologies['worker-robots-speed-5'].enabled = false | ||||
|             force.technologies['worker-robots-speed-6'].enabled = false | ||||
|             this.spaghetti_enabled = true | ||||
|         elseif param == 'false' then | ||||
|             if this.spaghetti_enabled == false or this.spaghetti_enabled == nil then | ||||
|                 player.print('Spaghetti is already disabled.', Color.yellow) | ||||
|                 return | ||||
|             end | ||||
|             game.print('The world is no longer spaghett!', Color.yellow) | ||||
|             force.technologies['logistic-system'].enabled = true | ||||
|             force.technologies['construction-robotics'].enabled = true | ||||
|             force.technologies['logistic-robotics'].enabled = true | ||||
|             force.technologies['robotics'].enabled = true | ||||
|             force.technologies['personal-roboport-equipment'].enabled = true | ||||
|             force.technologies['personal-roboport-mk2-equipment'].enabled = true | ||||
|             force.technologies['character-logistic-trash-slots-1'].enabled = true | ||||
|             force.technologies['character-logistic-trash-slots-2'].enabled = true | ||||
|             force.technologies['auto-character-logistic-trash-slots'].enabled = true | ||||
|             force.technologies['worker-robots-storage-1'].enabled = true | ||||
|             force.technologies['worker-robots-storage-2'].enabled = true | ||||
|             force.technologies['worker-robots-storage-3'].enabled = true | ||||
|             force.technologies['character-logistic-slots-1'].enabled = true | ||||
|             force.technologies['character-logistic-slots-2'].enabled = true | ||||
|             force.technologies['character-logistic-slots-3'].enabled = true | ||||
|             force.technologies['character-logistic-slots-4'].enabled = true | ||||
|             force.technologies['character-logistic-slots-5'].enabled = true | ||||
|             force.technologies['character-logistic-slots-6'].enabled = true | ||||
|             force.technologies['worker-robots-speed-1'].enabled = true | ||||
|             force.technologies['worker-robots-speed-2'].enabled = true | ||||
|             force.technologies['worker-robots-speed-3'].enabled = true | ||||
|             force.technologies['worker-robots-speed-4'].enabled = true | ||||
|             force.technologies['worker-robots-speed-5'].enabled = true | ||||
|             force.technologies['worker-robots-speed-6'].enabled = true | ||||
|             this.spaghetti_enabled = false | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'generate_map', | ||||
|     'Pregenerates map.', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
|         local param = tonumber(cmd.parameter) | ||||
|  | ||||
|         if not (player and player.valid) then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local p = player.print | ||||
|         if not player.admin then | ||||
|             p("[ERROR] You're not admin!", Color.fail) | ||||
|             return | ||||
|         end | ||||
|         if param == nil then | ||||
|             player.print('[ERROR] Must specify radius!', Color.fail) | ||||
|             return | ||||
|         end | ||||
|         if param > 50 then | ||||
|             player.print('[ERROR] Value is too big.', Color.fail) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if not this.generate_map then | ||||
|             this.generate_map = true | ||||
|             player.print('[WARNING] This command will make the server LAG, run this command again if you really want to do this!', Color.yellow) | ||||
|             return | ||||
|         end | ||||
|         local radius = param | ||||
|         local surface = game.players[1].surface | ||||
|         if surface.is_chunk_generated({radius, radius}) then | ||||
|             game.print('Map generation done!', Color.success) | ||||
|             this.generate_map = nil | ||||
|             return | ||||
|         end | ||||
|         surface.request_to_generate_chunks({0, 0}, radius) | ||||
|         surface.force_generate_chunk_requests() | ||||
|         for _, pl in pairs(game.connected_players) do | ||||
|             pl.play_sound {path = 'utility/new_objective', volume_modifier = 1} | ||||
|         end | ||||
|         game.print('Map generation done!', Color.success) | ||||
|         this.generate_map = nil | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'repair', | ||||
|     'Revives all ghost entities.', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
|         local param = tonumber(cmd.parameter) | ||||
|  | ||||
|         if not (player and player.valid) then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local p = player.print | ||||
|         if not player.admin then | ||||
|             p("[ERROR] You're not admin!", Color.fail) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == nil then | ||||
|             player.print('[ERROR] Must specify radius!', Color.fail) | ||||
|             return | ||||
|         end | ||||
|         if param > 50 then | ||||
|             player.print('[ERROR] Value is too big.', Color.fail) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if not this.revive_warning then | ||||
|             this.revive_warning = true | ||||
|             player.print('[WARNING] This command will revive all the ghost entities in the given radius, run this command again if you really want to do this!', Color.yellow) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local radius = {{x = (player.position.x + -param), y = (player.position.y + -param)}, {x = (player.position.x + param), y = (player.position.y + param)}} | ||||
|  | ||||
|         local c = 0 | ||||
|         for _, v in pairs(player.surface.find_entities_filtered {type = 'entity-ghost', area = radius}) do | ||||
|             if v and v.valid then | ||||
|                 c = c + 1 | ||||
|                 v.silent_revive() | ||||
| Commands.new('spaghetti', 'Toggle between disabling bots.') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :is_activated() | ||||
|     :add_parameter('true/false', true, 'boolean') | ||||
|     :callback( | ||||
|         function (player, args) | ||||
|             local force = player.force | ||||
|             if args == 'true' then | ||||
|                 game.print('The world has been spaghettified!', Color.success) | ||||
|                 force.technologies['logistic-system'].enabled = false | ||||
|                 force.technologies['construction-robotics'].enabled = false | ||||
|                 force.technologies['logistic-robotics'].enabled = false | ||||
|                 force.technologies['robotics'].enabled = false | ||||
|                 force.technologies['personal-roboport-equipment'].enabled = false | ||||
|                 force.technologies['personal-roboport-mk2-equipment'].enabled = false | ||||
|                 force.technologies['worker-robots-storage-1'].enabled = false | ||||
|                 force.technologies['worker-robots-storage-2'].enabled = false | ||||
|                 force.technologies['worker-robots-storage-3'].enabled = false | ||||
|                 force.technologies['worker-robots-speed-1'].enabled = false | ||||
|                 force.technologies['worker-robots-speed-2'].enabled = false | ||||
|                 force.technologies['worker-robots-speed-3'].enabled = false | ||||
|                 force.technologies['worker-robots-speed-4'].enabled = false | ||||
|                 force.technologies['worker-robots-speed-5'].enabled = false | ||||
|                 force.technologies['worker-robots-speed-6'].enabled = false | ||||
|                 this.spaghetti_enabled = true | ||||
|             elseif args == 'false' then | ||||
|                 game.print('The world is no longer spaghett!', Color.yellow) | ||||
|                 force.technologies['logistic-system'].enabled = true | ||||
|                 force.technologies['construction-robotics'].enabled = true | ||||
|                 force.technologies['logistic-robotics'].enabled = true | ||||
|                 force.technologies['robotics'].enabled = true | ||||
|                 force.technologies['personal-roboport-equipment'].enabled = true | ||||
|                 force.technologies['personal-roboport-mk2-equipment'].enabled = true | ||||
|                 force.technologies['worker-robots-storage-1'].enabled = true | ||||
|                 force.technologies['worker-robots-storage-2'].enabled = true | ||||
|                 force.technologies['worker-robots-storage-3'].enabled = true | ||||
|                 force.technologies['worker-robots-speed-1'].enabled = true | ||||
|                 force.technologies['worker-robots-speed-2'].enabled = true | ||||
|                 force.technologies['worker-robots-speed-3'].enabled = true | ||||
|                 force.technologies['worker-robots-speed-4'].enabled = true | ||||
|                 force.technologies['worker-robots-speed-5'].enabled = true | ||||
|                 force.technologies['worker-robots-speed-6'].enabled = true | ||||
|                 this.spaghetti_enabled = false | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         if c == 0 then | ||||
|             player.print('No entities to repair were found!', Color.warning) | ||||
|             this.revive_warning = nil | ||||
|             return | ||||
| Commands.new('generate_map', 'Pregenerates map.') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :add_parameter('radius', false, 'number') | ||||
|     :callback( | ||||
|         function (player, args) | ||||
|             local radius = args | ||||
|             local surface = player.surface | ||||
|             if surface.is_chunk_generated({ radius, radius }) then | ||||
|                 player.print('Map generation done') | ||||
|                 return true | ||||
|             end | ||||
|             surface.request_to_generate_chunks({ 0, 0 }, radius) | ||||
|             surface.force_generate_chunk_requests() | ||||
|             for _, pl in pairs(game.connected_players) do | ||||
|                 pl.play_sound { path = 'utility/new_objective', volume_modifier = 1 } | ||||
|             end | ||||
|             player.print('Map generation done') | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         Discord.send_notification_raw(nil, player.name .. ' repaired ' .. c .. ' entities!') | ||||
| Commands.new('repair', 'Revives all ghost entities.') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :add_parameter('1-50', true, 'number') | ||||
|     :callback( | ||||
|         function (player, args) | ||||
|             if args < 1 then | ||||
|                 player.print('[ERROR] Value is too low.') | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
|         player.play_sound {path = 'utility/new_objective', volume_modifier = 1} | ||||
|         player.print('Repaired ' .. c .. ' entities!', Color.success) | ||||
|         this.revive_warning = nil | ||||
|     end | ||||
| ) | ||||
|             if args > 50 then | ||||
|                 player.print('[ERROR] Value is too big.') | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
| commands.add_command( | ||||
|     'dump_layout', | ||||
|     'Dump the current map-layout.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|             local radius = { { x = (player.position.x + -args), y = (player.position.y + -args) }, { x = (player.position.x + args), y = (player.position.y + args) } } | ||||
|  | ||||
|         if not (player and player.valid) then | ||||
|             return | ||||
|             local c = 0 | ||||
|             for _, v in pairs(player.surface.find_entities_filtered { type = 'entity-ghost', area = radius }) do | ||||
|                 if v and v.valid then | ||||
|                     c = c + 1 | ||||
|                     v.silent_revive() | ||||
|                 end | ||||
|             end | ||||
|  | ||||
|             if c == 0 then | ||||
|                 player.print('No entities to repair were found!') | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
|             Discord.send_notification_raw(nil, player.name .. ' repaired ' .. c .. ' entities!') | ||||
|             return 'Repaired ' .. c .. ' entities!' | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         local p = player.print | ||||
|         if not player.admin then | ||||
|             p("[ERROR] You're not admin!", Color.warning) | ||||
|             return | ||||
|         end | ||||
|         if not this.dump_layout then | ||||
|             this.dump_layout = true | ||||
|             player.print('[WARNING] This command will make the server LAG, run this command again if you really want to do this!', Color.yellow) | ||||
|             return | ||||
|         end | ||||
|         local surface = game.players[1].surface | ||||
|         game.write_file('layout.lua', '', false) | ||||
| Commands.new('dump_layout', 'Dump the current map-layout.') | ||||
|     :require_admin() | ||||
|     :require_validation('This will lag the server if ran') | ||||
|     :callback( | ||||
|         function (player, _) | ||||
|             local surface = player.surface | ||||
|             game.write_file('layout.lua', '', false) | ||||
|  | ||||
|         local area = { | ||||
|             left_top = {x = 0, y = 0}, | ||||
|             right_bottom = {x = 32, y = 32} | ||||
|         } | ||||
|             local area = { | ||||
|                 left_top = { x = 0, y = 0 }, | ||||
|                 right_bottom = { x = 32, y = 32 } | ||||
|             } | ||||
|  | ||||
|         local entities = surface.find_entities_filtered {area = area} | ||||
|         local tiles = surface.find_tiles_filtered {area = area} | ||||
|             local entities = surface.find_entities_filtered { area = area } | ||||
|             local tiles = surface.find_tiles_filtered { area = area } | ||||
|  | ||||
|         for _, e in pairs(entities) do | ||||
|             local str = '{position = {x = ' .. e.position.x | ||||
|             str = str .. ', y = ' | ||||
|             str = str .. e.position.y | ||||
|             str = str .. '}, name = "' | ||||
|             str = str .. e.name | ||||
|             str = str .. '", direction = ' | ||||
|             str = str .. tostring(e.direction) | ||||
|             str = str .. ', force = "' | ||||
|             str = str .. e.force.name | ||||
|             str = str .. '"},' | ||||
|             if e.name ~= 'character' then | ||||
|             for _, e in pairs(entities) do | ||||
|                 local str = '{position = {x = ' .. e.position.x | ||||
|                 str = str .. ', y = ' | ||||
|                 str = str .. e.position.y | ||||
|                 str = str .. '}, name = "' | ||||
|                 str = str .. e.name | ||||
|                 str = str .. '", direction = ' | ||||
|                 str = str .. tostring(e.direction) | ||||
|                 str = str .. ', force = "' | ||||
|                 str = str .. e.force.name | ||||
|                 str = str .. '"},' | ||||
|                 if e.name ~= 'character' then | ||||
|                     game.write_file('layout.lua', str .. '\n', true) | ||||
|                 end | ||||
|             end | ||||
|  | ||||
|             game.write_file('layout.lua', '\n', true) | ||||
|             game.write_file('layout.lua', '\n', true) | ||||
|             game.write_file('layout.lua', 'Tiles: \n', true) | ||||
|  | ||||
|             for _, t in pairs(tiles) do | ||||
|                 local str = '{position = {x = ' .. t.position.x | ||||
|                 str = str .. ', y = ' | ||||
|                 str = str .. t.position.y | ||||
|                 str = str .. '}, name = "' | ||||
|                 str = str .. t.name | ||||
|                 str = str .. '"},' | ||||
|                 game.write_file('layout.lua', str .. '\n', true) | ||||
|             end | ||||
|             return 'Dumped layout as file: layout.lua' | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         game.write_file('layout.lua', '\n', true) | ||||
|         game.write_file('layout.lua', '\n', true) | ||||
|         game.write_file('layout.lua', 'Tiles: \n', true) | ||||
| Commands.new('creative', 'Enables creative_mode.') | ||||
|     :require_admin() | ||||
|     :add_parameter('true/false', false, 'boolean') | ||||
|     :require_validation() | ||||
|     :is_activated() | ||||
|     :callback( | ||||
|         function (player, args) | ||||
|             local force = player.force | ||||
|             if args == 'true' then | ||||
|                 game.print('[CREATIVE] ' .. player.name .. ' has activated creative-mode!', Color.warning) | ||||
|                 Server.to_discord_bold(table.concat { '[Creative] ' .. player.name .. ' has activated creative-mode!' }) | ||||
|  | ||||
|         for _, t in pairs(tiles) do | ||||
|             local str = '{position = {x = ' .. t.position.x | ||||
|             str = str .. ', y = ' | ||||
|             str = str .. t.position.y | ||||
|             str = str .. '}, name = "' | ||||
|             str = str .. t.name | ||||
|             str = str .. '"},' | ||||
|             game.write_file('layout.lua', str .. '\n', true) | ||||
|             player.print('Dumped layout as file: layout.lua', Color.success) | ||||
|         end | ||||
|         this.dump_layout = false | ||||
|     end | ||||
| ) | ||||
|                 Modifiers.set('creative_enabled', true) | ||||
|  | ||||
| commands.add_command( | ||||
|     'creative', | ||||
|     'Enables creative_mode.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not (player and player.valid) then | ||||
|             return | ||||
|         end | ||||
|                 this.creative_enabled = true | ||||
|  | ||||
|         local p = player.print | ||||
|         if not player.admin then | ||||
|             p("[ERROR] You're not admin!", Color.fail) | ||||
|             return | ||||
|         end | ||||
|         if not this.creative_are_you_sure then | ||||
|             this.creative_are_you_sure = true | ||||
|             player.print('[WARNING] This command will enable creative/cheat-mode for all connected players, run this command again if you really want to do this!', Color.yellow) | ||||
|             return | ||||
|         end | ||||
|         if this.creative_enabled then | ||||
|             player.print('[ERROR] Creative/cheat-mode is already active!', Color.fail) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         game.print('[CREATIVE] ' .. player.name .. ' has activated creative-mode!', Color.warning) | ||||
|         Server.to_discord_bold(table.concat {'[Creative] ' .. player.name .. ' has activated creative-mode!'}) | ||||
|  | ||||
|         Modifiers.set('creative_enabled', true) | ||||
|  | ||||
|         player.force.enable_all_prototypes() | ||||
|         this.creative_enabled = true | ||||
|         this.creative_are_you_sure = false | ||||
|  | ||||
|         for _, _player in pairs(game.connected_players) do | ||||
|             if _player.character ~= nil then | ||||
|                 Public.insert_all_items(_player) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'delete-uncharted-chunks', | ||||
|     'Deletes all chunks that are not charted. Can reduce filesize of the savegame. May be unsafe to use in certain custom maps.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not (player and player.valid) then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local p = player.print | ||||
|         if not player.admin then | ||||
|             p("[ERROR] You're not admin!", Color.fail) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local forces = {} | ||||
|         for _, force in pairs(game.forces) do | ||||
|             if force.index == 1 or force.index > 3 then | ||||
|                 table.insert(forces, force) | ||||
|             end | ||||
|         end | ||||
|  | ||||
|         local is_charted | ||||
|         local count = 0 | ||||
|         for _, surface in pairs(game.surfaces) do | ||||
|             for chunk in surface.get_chunks() do | ||||
|                 is_charted = false | ||||
|                 for _, force in pairs(forces) do | ||||
|                     if force.is_chunk_charted(surface, {chunk.x, chunk.y}) then | ||||
|                         is_charted = true | ||||
|                         break | ||||
|                 force.enable_all_prototypes() | ||||
|                 for _, _player in pairs(game.connected_players) do | ||||
|                     player.cheat_mode = true | ||||
|                     if _player.character ~= nil then | ||||
|                         Public.insert_all_items(_player) | ||||
|                     end | ||||
|                 end | ||||
|                 if not is_charted then | ||||
|                     surface.delete_chunk({chunk.x, chunk.y}) | ||||
|                     count = count + 1 | ||||
|             elseif args == 'false' then | ||||
|                 game.print('[CREATIVE] ' .. player.name .. ' has deactivated creative-mode!', Color.warning) | ||||
|                 Server.to_discord_bold(table.concat { '[Creative] ' .. player.name .. ' has deactivated creative-mode!' }) | ||||
|  | ||||
|                 Modifiers.set('creative_enabled', false) | ||||
|  | ||||
|                 this.creative_enabled = false | ||||
|  | ||||
|                 for _, _player in pairs(game.connected_players) do | ||||
|                     Public.remove_all_items(player) | ||||
|                     _player.cheat_mode = false | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         local message = player.name .. ' deleted ' .. count .. ' uncharted chunks!' | ||||
|         game.print(message, Color.warning) | ||||
|         Server.to_discord_bold(table.concat {message}) | ||||
|     end | ||||
| ) | ||||
| Commands.new('delete_uncharted_chunks', 'Deletes all chunks that are not charted. Can reduce filesize of the savegame. May be unsafe to use in certain custom maps.') | ||||
|     :require_admin() | ||||
|     :require_validation() | ||||
|     :callback( | ||||
|         function (player, _) | ||||
|             local forces = {} | ||||
|             for _, force in pairs(game.forces) do | ||||
|                 if force.index == 1 or force.index > 3 then | ||||
|                     table.insert(forces, force) | ||||
|                 end | ||||
|             end | ||||
|  | ||||
|             local is_charted | ||||
|             local count = 0 | ||||
|             for _, surface in pairs(game.surfaces) do | ||||
|                 for chunk in surface.get_chunks() do | ||||
|                     is_charted = false | ||||
|                     for _, force in pairs(forces) do | ||||
|                         if force.is_chunk_charted(surface, { chunk.x, chunk.y }) then | ||||
|                             is_charted = true | ||||
|                             break | ||||
|                         end | ||||
|                     end | ||||
|                     if not is_charted then | ||||
|                         surface.delete_chunk({ chunk.x, chunk.y }) | ||||
|                         count = count + 1 | ||||
|                     end | ||||
|                 end | ||||
|             end | ||||
|  | ||||
|             local message = player.name .. ' deleted ' .. count .. ' uncharted chunks!' | ||||
|             game.print(message, Color.warning) | ||||
|             Server.to_discord_bold(table.concat { message }) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| local function clear_corpses(cmd) | ||||
|     local player | ||||
| @@ -410,9 +314,9 @@ local function clear_corpses(cmd) | ||||
|  | ||||
|     local i = 0 | ||||
|  | ||||
|     local radius = {{x = (pos.x + -param), y = (pos.y + -param)}, {x = (pos.x + param), y = (pos.y + param)}} | ||||
|     local radius = { { x = (pos.x + -param), y = (pos.y + -param) }, { x = (pos.x + param), y = (pos.y + param) } } | ||||
|  | ||||
|     for _, entity in pairs(player.surface.find_entities_filtered {area = radius, type = 'corpse'}) do | ||||
|     for _, entity in pairs(player.surface.find_entities_filtered { area = radius, type = 'corpse' }) do | ||||
|         if entity.corpse_expires then | ||||
|             entity.destroy() | ||||
|             i = i + 1 | ||||
| @@ -433,12 +337,12 @@ end | ||||
| commands.add_command( | ||||
|     'clear-corpses', | ||||
|     'Clears all the biter corpses..', | ||||
|     function(cmd) | ||||
|     function (cmd) | ||||
|         clear_corpses(cmd) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| local on_player_joined_game = function(player) | ||||
| local on_player_joined_game = function (player) | ||||
|     Public.insert_all_items(player) | ||||
| end | ||||
|  | ||||
| @@ -448,7 +352,7 @@ function Public.insert_all_items(player) | ||||
|             if player.get_inventory(defines.inventory.character_armor) then | ||||
|                 player.get_inventory(defines.inventory.character_armor).clear() | ||||
|             end | ||||
|             player.insert {name = 'power-armor-mk2', count = 1} | ||||
|             player.insert { name = 'power-armor-mk2', count = 1 } | ||||
|             Modifiers.update_single_modifier(player, 'character_inventory_slots_bonus', 'creative', #game.item_prototypes) | ||||
|             Modifiers.update_single_modifier(player, 'character_mining_speed_modifier', 'creative', 150) | ||||
|             Modifiers.update_single_modifier(player, 'character_health_bonus', 'creative', 2000) | ||||
| @@ -461,20 +365,20 @@ function Public.insert_all_items(player) | ||||
|  | ||||
|             local p_armor = player.get_inventory(5)[1].grid | ||||
|             if p_armor and p_armor.valid then | ||||
|                 p_armor.put({name = 'fusion-reactor-equipment'}) | ||||
|                 p_armor.put({name = 'fusion-reactor-equipment'}) | ||||
|                 p_armor.put({name = 'fusion-reactor-equipment'}) | ||||
|                 p_armor.put({name = 'exoskeleton-equipment'}) | ||||
|                 p_armor.put({name = 'exoskeleton-equipment'}) | ||||
|                 p_armor.put({name = 'exoskeleton-equipment'}) | ||||
|                 p_armor.put({name = 'energy-shield-mk2-equipment'}) | ||||
|                 p_armor.put({name = 'energy-shield-mk2-equipment'}) | ||||
|                 p_armor.put({name = 'energy-shield-mk2-equipment'}) | ||||
|                 p_armor.put({name = 'energy-shield-mk2-equipment'}) | ||||
|                 p_armor.put({name = 'personal-roboport-mk2-equipment'}) | ||||
|                 p_armor.put({name = 'night-vision-equipment'}) | ||||
|                 p_armor.put({name = 'battery-mk2-equipment'}) | ||||
|                 p_armor.put({name = 'battery-mk2-equipment'}) | ||||
|                 p_armor.put({ name = 'fusion-reactor-equipment' }) | ||||
|                 p_armor.put({ name = 'fusion-reactor-equipment' }) | ||||
|                 p_armor.put({ name = 'fusion-reactor-equipment' }) | ||||
|                 p_armor.put({ name = 'exoskeleton-equipment' }) | ||||
|                 p_armor.put({ name = 'exoskeleton-equipment' }) | ||||
|                 p_armor.put({ name = 'exoskeleton-equipment' }) | ||||
|                 p_armor.put({ name = 'energy-shield-mk2-equipment' }) | ||||
|                 p_armor.put({ name = 'energy-shield-mk2-equipment' }) | ||||
|                 p_armor.put({ name = 'energy-shield-mk2-equipment' }) | ||||
|                 p_armor.put({ name = 'energy-shield-mk2-equipment' }) | ||||
|                 p_armor.put({ name = 'personal-roboport-mk2-equipment' }) | ||||
|                 p_armor.put({ name = 'night-vision-equipment' }) | ||||
|                 p_armor.put({ name = 'battery-mk2-equipment' }) | ||||
|                 p_armor.put({ name = 'battery-mk2-equipment' }) | ||||
|             end | ||||
|             local item = game.item_prototypes | ||||
|             local i = 0 | ||||
| @@ -482,7 +386,7 @@ function Public.insert_all_items(player) | ||||
|                 i = i + 1 | ||||
|                 if _k and _v.type ~= 'mining-tool' then | ||||
|                     player.character_inventory_slots_bonus = Modifiers.get_single_modifier(player, 'character_inventory_slots_bonus', 'creative') | ||||
|                     player.insert {name = _k, count = _v.stack_size} | ||||
|                     player.insert { name = _k, count = _v.stack_size } | ||||
|                     player.print('[CREATIVE] Inserted all base items.', Color.success) | ||||
|                 end | ||||
|             end | ||||
| @@ -490,6 +394,17 @@ function Public.insert_all_items(player) | ||||
|     end | ||||
| end | ||||
|  | ||||
| function Public.remove_all_items(player) | ||||
|     if player.character ~= nil then | ||||
|         if player.get_inventory(defines.inventory.character_armor) then | ||||
|             player.get_inventory(defines.inventory.character_armor).clear() | ||||
|         end | ||||
|         player.clear_items_inside() | ||||
|         Modifiers.reset_player_modifiers(player) | ||||
|         this.players[player.index] = nil | ||||
|     end | ||||
| end | ||||
|  | ||||
| local function create_clear_corpse_frame(player, bottom_frame_data) | ||||
|     local button | ||||
|  | ||||
| @@ -498,17 +413,17 @@ local function create_clear_corpse_frame(player, bottom_frame_data) | ||||
|     if Gui.get_mod_gui_top_frame() then | ||||
|         button = | ||||
|             Gui.add_mod_button( | ||||
|             player, | ||||
|             { | ||||
|                 type = 'sprite-button', | ||||
|                 name = clear_corpse_button_name, | ||||
|                 sprite = 'entity/behemoth-biter', | ||||
|                 tooltip = {'commands.clear_corpse'}, | ||||
|                 style = Gui.button_style | ||||
|             } | ||||
|         ) | ||||
|                 player, | ||||
|                 { | ||||
|                     type = 'sprite-button', | ||||
|                     name = clear_corpse_button_name, | ||||
|                     sprite = 'entity/behemoth-biter', | ||||
|                     tooltip = { 'commands.clear_corpse' }, | ||||
|                     style = Gui.button_style | ||||
|                 } | ||||
|             ) | ||||
|         if button then | ||||
|             button.style.font_color = {165, 165, 165} | ||||
|             button.style.font_color = { 165, 165, 165 } | ||||
|             button.style.font = 'heading-3' | ||||
|             button.style.minimal_height = 36 | ||||
|             button.style.maximal_height = 36 | ||||
| @@ -523,11 +438,11 @@ local function create_clear_corpse_frame(player, bottom_frame_data) | ||||
|                     type = 'sprite-button', | ||||
|                     sprite = 'entity/behemoth-biter', | ||||
|                     name = clear_corpse_button_name, | ||||
|                     tooltip = {'commands.clear_corpse'}, | ||||
|                     tooltip = { 'commands.clear_corpse' }, | ||||
|                     style = Gui.button_style | ||||
|                 } | ||||
|             ) | ||||
|         button.style.font_color = {r = 0.11, g = 0.8, b = 0.44} | ||||
|         button.style.font_color = { r = 0.11, g = 0.8, b = 0.44 } | ||||
|         button.style.font = 'heading-1' | ||||
|         button.style.minimal_height = 40 | ||||
|         button.style.maximal_width = 40 | ||||
| @@ -564,7 +479,7 @@ function Public.set(key, value) | ||||
| end | ||||
|  | ||||
| Event.on_init( | ||||
|     function() | ||||
|     function () | ||||
|         Modifiers.set('creative_enabled', false) | ||||
|         this.creative_are_you_sure = false | ||||
|         this.creative_enabled = false | ||||
| @@ -588,20 +503,20 @@ end | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.players[event.player_index] | ||||
|         on_player_joined_game(player) | ||||
|         create_clear_corpse_frame(player) | ||||
|  | ||||
|         if this.bottom_button then | ||||
|             BottomFrame.add_inner_frame({player = player, element_name = clear_corpse_button_name, tooltip = {'commands.clear_corpse'}, sprite = 'entity/behemoth-biter'}) | ||||
|             BottomFrame.add_inner_frame({ player = player, element_name = clear_corpse_button_name, tooltip = { 'commands.clear_corpse' }, sprite = 'entity/behemoth-biter' }) | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Gui.on_click( | ||||
|     clear_corpse_button_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Clear Corpse') | ||||
|         if is_spamming then | ||||
|             return | ||||
| @@ -612,7 +527,7 @@ Gui.on_click( | ||||
|  | ||||
| Event.add( | ||||
|     BottomFrame.events.bottom_quickbar_location_changed, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player_index = event.player_index | ||||
|         if not player_index then | ||||
|             return | ||||
|   | ||||
| @@ -1,103 +1,55 @@ | ||||
| local Event = require 'utils.event' | ||||
| local Session = require 'utils.datastore.session_data' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| commands.add_command( | ||||
|     'trust', | ||||
|     'Promotes a player to trusted!', | ||||
|     function(cmd) | ||||
|  | ||||
| Commands.new('trust', 'Promotes a player to trusted!') | ||||
|     :require_admin() | ||||
|     :add_parameter('player', false, 'player') | ||||
|     :callback(function (player, target_player) | ||||
|         local trusted = Session.get_trusted_table() | ||||
|         local player = game.player | ||||
|  | ||||
|         if player and player.valid then | ||||
|             if not player.admin then | ||||
|                 player.print("You're not admin!", {r = 1, g = 0.5, b = 0.1}) | ||||
|                 return | ||||
|         if target_player then | ||||
|             if trusted[target_player.name] then | ||||
|                 game.print(target_player.name .. ' is already trusted!') | ||||
|                 return false | ||||
|             end | ||||
|             trusted[target_player.name] = true | ||||
|             game.print(target_player.name .. ' is now a trusted player.', { r = 0.22, g = 0.99, b = 0.99 }) | ||||
|  | ||||
|             if cmd.parameter == nil then | ||||
|                 return | ||||
|             end | ||||
|             local target_player = game.get_player(cmd.parameter) | ||||
|             if target_player then | ||||
|                 if trusted[target_player.name] then | ||||
|                     game.print(target_player.name .. ' is already trusted!') | ||||
|                     return | ||||
|             for _, a in pairs(game.connected_players) do | ||||
|                 if a.admin and a.name ~= player.name then | ||||
|                     a.print('[ADMIN]: ' .. player.name .. ' trusted ' .. target_player.name, { r = 1, g = 0.5, b = 0.1 }) | ||||
|                 end | ||||
|                 trusted[target_player.name] = true | ||||
|                 game.print(target_player.name .. ' is now a trusted player.', {r = 0.22, g = 0.99, b = 0.99}) | ||||
|                 for _, a in pairs(game.connected_players) do | ||||
|                     if a.admin and a.name ~= player.name then | ||||
|                         a.print('[ADMIN]: ' .. player.name .. ' trusted ' .. target_player.name, {r = 1, g = 0.5, b = 0.1}) | ||||
|                     end | ||||
|                 end | ||||
|             end | ||||
|         else | ||||
|             if cmd.parameter == nil then | ||||
|                 return | ||||
|             end | ||||
|             local target_player = game.get_player(cmd.parameter) | ||||
|             if target_player then | ||||
|                 if trusted[target_player.name] == true then | ||||
|                     game.print(target_player.name .. ' is already trusted!') | ||||
|                     return | ||||
|                 end | ||||
|                 trusted[target_player.name] = true | ||||
|                 game.print(target_player.name .. ' is now a trusted player.', {r = 0.22, g = 0.99, b = 0.99}) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     end) | ||||
|  | ||||
| commands.add_command( | ||||
|     'untrust', | ||||
|     'Demotes a player from trusted!', | ||||
|     function(cmd) | ||||
| Commands.new('untrust', 'Demotes a player from trusted!') | ||||
|     :require_admin() | ||||
|     :add_parameter('player', false, 'player') | ||||
|     :callback(function (player, target_player) | ||||
|         local trusted = Session.get_trusted_table() | ||||
|         local player = game.player | ||||
|  | ||||
|         if player and player.valid then | ||||
|             if not player.admin then | ||||
|                 player.print("You're not admin!", {r = 1, g = 0.5, b = 0.1}) | ||||
|                 return | ||||
|         if target_player then | ||||
|             if trusted[target_player.name] == false then | ||||
|                 game.print(target_player.name .. ' is already untrusted!') | ||||
|                 return false | ||||
|             end | ||||
|             trusted[target_player.name] = false | ||||
|             game.print(target_player.name .. ' is now untrusted.', { r = 0.22, g = 0.99, b = 0.99 }) | ||||
|  | ||||
|             if cmd.parameter == nil then | ||||
|                 return | ||||
|             end | ||||
|             local target_player = game.get_player(cmd.parameter) | ||||
|             if target_player then | ||||
|                 if trusted[target_player.name] == false then | ||||
|                     game.print(target_player.name .. ' is already untrusted!') | ||||
|                     return | ||||
|             for _, a in pairs(game.connected_players) do | ||||
|                 if a.admin and a.name ~= player.name then | ||||
|                     a.print('[ADMIN]: ' .. player.name .. ' untrusted ' .. target_player.name, { r = 1, g = 0.5, b = 0.1 }) | ||||
|                 end | ||||
|                 trusted[target_player.name] = false | ||||
|                 game.print(target_player.name .. ' is now untrusted.', {r = 0.22, g = 0.99, b = 0.99}) | ||||
|                 for _, a in pairs(game.connected_players) do | ||||
|                     if a.admin == true and a.name ~= player.name then | ||||
|                         a.print('[ADMIN]: ' .. player.name .. ' untrusted ' .. target_player.name, {r = 1, g = 0.5, b = 0.1}) | ||||
|                     end | ||||
|                 end | ||||
|             end | ||||
|         else | ||||
|             if cmd.parameter == nil then | ||||
|                 return | ||||
|             end | ||||
|             local target_player = game.get_player(cmd.parameter) | ||||
|             if target_player then | ||||
|                 if trusted[target_player.name] == false then | ||||
|                     game.print(target_player.name .. ' is already untrusted!') | ||||
|                     return | ||||
|                 end | ||||
|                 trusted[target_player.name] = false | ||||
|                 game.print(target_player.name .. ' is now untrusted.', {r = 0.22, g = 0.99, b = 0.99}) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     end) | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_created, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not (player and player.valid) then | ||||
|             return | ||||
|   | ||||
| @@ -5,6 +5,7 @@ local Event = require 'utils.event' | ||||
| local Global = require 'utils.global' | ||||
| local Gui = require 'utils.gui' | ||||
| local SpamProtection = require 'utils.spam_protection' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local this = { | ||||
|     players = {}, | ||||
| @@ -13,7 +14,7 @@ local this = { | ||||
|  | ||||
| Global.register( | ||||
|     this, | ||||
|     function(t) | ||||
|     function (t) | ||||
|         this = t | ||||
|     end | ||||
| ) | ||||
| @@ -91,7 +92,7 @@ local function create_mini_camera_gui(player, target, zoom, render, tooltip) | ||||
|  | ||||
|     local frame = player.gui.screen[locate_player_frame_name] | ||||
|     if not validate_frame(frame) then | ||||
|         frame = player.gui.screen.add({type = 'frame', name = locate_player_frame_name, caption = target.name}) | ||||
|         frame = player.gui.screen.add({ type = 'frame', name = locate_player_frame_name, caption = target.name }) | ||||
|     end | ||||
|  | ||||
|     frame.force_auto_center() | ||||
| @@ -105,16 +106,16 @@ local function create_mini_camera_gui(player, target, zoom, render, tooltip) | ||||
|     if render then | ||||
|         local render_object = | ||||
|             rendering.draw_text { | ||||
|             text = '▼', | ||||
|             surface = target.surface, | ||||
|             target = {target.position.x, target.position.y - 3}, | ||||
|             color = {r = 0.98, g = 0.66, b = 0.22}, | ||||
|             scale = 3, | ||||
|             players = {player.index}, | ||||
|             font = 'heading-1', | ||||
|             alignment = 'center', | ||||
|             scale_with_zoom = false | ||||
|         } | ||||
|                 text = '▼', | ||||
|                 surface = target.surface, | ||||
|                 target = { target.position.x, target.position.y - 3 }, | ||||
|                 color = { r = 0.98, g = 0.66, b = 0.22 }, | ||||
|                 scale = 3, | ||||
|                 players = { player.index }, | ||||
|                 font = 'heading-1', | ||||
|                 alignment = 'center', | ||||
|                 scale_with_zoom = false | ||||
|             } | ||||
|  | ||||
|         if player_data then | ||||
|             player_data.render_object = render_object | ||||
| @@ -123,15 +124,15 @@ local function create_mini_camera_gui(player, target, zoom, render, tooltip) | ||||
|  | ||||
|     local camera = | ||||
|         frame.add( | ||||
|         { | ||||
|             type = 'camera', | ||||
|             name = player_frame_name, | ||||
|             position = target.position, | ||||
|             zoom = zoom or 0.4, | ||||
|             surface_index = surface, | ||||
|             tooltip = tooltip or '' | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'camera', | ||||
|                 name = player_frame_name, | ||||
|                 position = target.position, | ||||
|                 zoom = zoom or 0.4, | ||||
|                 surface_index = surface, | ||||
|                 tooltip = tooltip or '' | ||||
|             } | ||||
|         ) | ||||
|     camera.style.minimal_width = 740 | ||||
|     camera.style.minimal_height = 580 | ||||
|     player_data = create_player_data(player) | ||||
| @@ -139,23 +140,14 @@ local function create_mini_camera_gui(player, target, zoom, render, tooltip) | ||||
|     return frame | ||||
| end | ||||
|  | ||||
| commands.add_command( | ||||
|     'where', | ||||
|     'Locates a player', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
|  | ||||
|         if player and player.valid then | ||||
|             if not cmd.parameter then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
| Commands.new('where', 'Locates a player') | ||||
|     :add_parameter('player', false, 'player-online') | ||||
|     :callback( | ||||
|         function (player, target) | ||||
|             if this.module_disabled then | ||||
|                 return | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
|             local target = game.get_player(cmd.parameter) | ||||
|  | ||||
|             if target and target.valid then | ||||
|                 local player_data = create_player_data(player) | ||||
|                 player_data.target = target | ||||
| @@ -164,11 +156,9 @@ commands.add_command( | ||||
|                 remove_player_data(player) | ||||
|                 player.print('[Where] Please type a name of a player who is connected.', Color.warning) | ||||
|             end | ||||
|         else | ||||
|             return | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
|  | ||||
| local function on_nth_tick() | ||||
|     for p, data in pairs(this.players) do | ||||
| @@ -197,7 +187,7 @@ end | ||||
|  | ||||
| Gui.on_click( | ||||
|     locate_player_frame_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Where Locate Player') | ||||
|         if is_spamming then | ||||
|             return | ||||
| @@ -208,7 +198,7 @@ Gui.on_click( | ||||
|  | ||||
| Gui.on_custom_close( | ||||
|     locate_player_frame_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Where Locate Player') | ||||
|         if is_spamming then | ||||
|             return | ||||
| @@ -219,7 +209,7 @@ Gui.on_custom_close( | ||||
|  | ||||
| Gui.on_click( | ||||
|     player_frame_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Where Player Frame') | ||||
|         if is_spamming then | ||||
|             return | ||||
|   | ||||
							
								
								
									
										3
									
								
								utils/common_commands.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								utils/common_commands.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| require 'utils.commands.trust_system' | ||||
| require 'utils.commands.misc' | ||||
| require 'utils.commands.where' | ||||
| @@ -138,6 +138,26 @@ function Public.iter_players(callback) | ||||
|     end | ||||
| end | ||||
|  | ||||
| function Public.output_message(value, color, player) | ||||
|     color = color and Color[color] or Color.white | ||||
|  | ||||
|     player = player or game.player | ||||
|  | ||||
|     local message = value and type(value) == 'table' and serpent.block(value) or value or type(value) == 'userdata' and 'Cannot output userdata' or 'Cannot output nil' | ||||
|  | ||||
|     if player then | ||||
|         player = player and type(player) == 'number' and game.get_player(player) and game.get_player(player).valid or player and player.valid and player or false | ||||
|         if not player then | ||||
|             error('Given player is not valid.', 2) | ||||
|         end | ||||
|  | ||||
|         player.play_sound { path = 'utility/scenario_message' } | ||||
|         player.print(message, color) | ||||
|     else | ||||
|         Server.output_data(message) | ||||
|     end | ||||
| end | ||||
|  | ||||
| function Public.cast_bool(var) | ||||
|     if var then | ||||
|         return true | ||||
| @@ -278,9 +298,9 @@ end | ||||
| -- @param command the command's name as table element | ||||
| -- @param parameters the command's parameters as a table (optional) | ||||
| function Public.log_command(actor, command, parameters) | ||||
|     local action = concat {'[Admin-Command] ', actor, ' used: ', command} | ||||
|     local action = concat { '[Admin-Command] ', actor, ' used: ', command } | ||||
|     if parameters then | ||||
|         action = concat {action, ' ', parameters} | ||||
|         action = concat { action, ' ', parameters } | ||||
|     end | ||||
|     print(action) | ||||
| end | ||||
| @@ -305,7 +325,7 @@ end | ||||
|  | ||||
| --- Returns a random RGB color as a table | ||||
| function Public.random_RGB() | ||||
|     return {r = random(0, 255), g = random(0, 255), b = random(0, 255)} | ||||
|     return { r = random(0, 255), g = random(0, 255), b = random(0, 255) } | ||||
| end | ||||
|  | ||||
| --- Sets a table element to value while also returning value. | ||||
| @@ -380,8 +400,9 @@ end | ||||
| --- Takes a string, number, or LuaPlayer and returns a valid LuaPlayer or nil. | ||||
| -- Intended for commands as there are extra checks in place. | ||||
| -- @param <string|number|LuaPlayer> | ||||
| -- @param <boolean> | ||||
| -- @return <LuaPlayer|nil> <string|nil> <number|nil> the LuaPlayer, their name, and their index | ||||
| function Public.validate_player(player_ident) | ||||
| function Public.validate_player(player_ident, check_admin) | ||||
|     local data_type = type(player_ident) | ||||
|     local player | ||||
|  | ||||
| @@ -400,6 +421,12 @@ function Public.validate_player(player_ident) | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     if check_admin then | ||||
|         if not player.admin then | ||||
|             return | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     return player, player.name, player.index | ||||
| end | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ local Token = require 'utils.token' | ||||
| local Color = require 'utils.color_presets' | ||||
| local Server = require 'utils.server' | ||||
| local Event = require 'utils.event' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local color_data_set = 'colors' | ||||
| local set_data = Server.set_data | ||||
| @@ -12,19 +13,19 @@ local Public = {} | ||||
|  | ||||
| local fetch = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local key = data.key | ||||
|         local value = data.value | ||||
|         local player = game.players[key] | ||||
|         if not player then | ||||
|             return | ||||
|         function (data) | ||||
|             local key = data.key | ||||
|             local value = data.value | ||||
|             local player = game.players[key] | ||||
|             if not player then | ||||
|                 return | ||||
|             end | ||||
|             if value then | ||||
|                 player.color = value.color[1] | ||||
|                 player.chat_color = value.chat[1] | ||||
|             end | ||||
|         end | ||||
|         if value then | ||||
|             player.color = value.color[1] | ||||
|             player.chat_color = value.chat[1] | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| --- Tries to get data from the webpanel and applies the value to the player. | ||||
| -- @param data_set player token | ||||
| @@ -41,7 +42,7 @@ local fetcher = Public.fetch | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player then | ||||
|             return | ||||
| @@ -50,45 +51,27 @@ Event.add( | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'save-color', | ||||
|     'Save your personal color preset so it´s always the same whenever you join.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|  | ||||
| Commands.new('save-color', "Save your personal color preset so it's always the same whenever you join.") | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             local color = player.color | ||||
|             local chat = player.chat_color | ||||
|  | ||||
|             set_data(color_data_set, player.name, { color = { color }, chat = { chat } }) | ||||
|             player.print('Your personal color has been saved to the datastore.', Color.success) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|         if not secs then | ||||
|             return | ||||
| Commands.new('remove-color', 'Removes your saved color from the datastore.') | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             set_data(color_data_set, player.name, nil) | ||||
|             player.print('Your personal color has been removed from the datastore.', Color.success) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         local color = player.color | ||||
|         local chat = player.chat_color | ||||
|  | ||||
|         set_data(color_data_set, player.name, {color = {color}, chat = {chat}}) | ||||
|         player.print('Your personal color has been saved to the datastore.', Color.success) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'remove-color', | ||||
|     'Removes your saved color from the datastore.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|         if not secs then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         set_data(color_data_set, player.name, nil) | ||||
|         player.print('Your personal color has been removed from the datastore.', Color.success) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -1,131 +0,0 @@ | ||||
| -- created by Gerkiz for ComfyFactorio | ||||
| local Server = require 'utils.server' | ||||
| local Event = require 'utils.event' | ||||
| local Gui = require 'utils.gui' | ||||
| local Color = require 'utils.color_presets' | ||||
|  | ||||
| local current_time_label = 'current_time_label' | ||||
|  | ||||
| local function validate_player(player) | ||||
|     if not player then | ||||
|         return false | ||||
|     end | ||||
|     if not player.valid then | ||||
|         return false | ||||
|     end | ||||
|     return true | ||||
| end | ||||
|  | ||||
| local function set_location(player) | ||||
|     local gui = player.gui | ||||
|     local label = gui.screen[current_time_label] | ||||
|     if not label or not label.valid then | ||||
|         return | ||||
|     end | ||||
|     local res = player.display_resolution | ||||
|     local uis = player.display_scale | ||||
|     label.location = {x = res.width - 423 * uis, y = 50 * uis} | ||||
| end | ||||
|  | ||||
| local function create_label(player) | ||||
|     local date = Server.get_current_date_with_time() | ||||
|     if not date then | ||||
|         date = '1970-01-01' | ||||
|     end | ||||
|  | ||||
|     local label = | ||||
|         player.gui.screen.add( | ||||
|         { | ||||
|             type = 'label', | ||||
|             name = current_time_label, | ||||
|             caption = date | ||||
|         } | ||||
|     ) | ||||
|     local style = label.style | ||||
|     style.font = 'default-game' | ||||
|     return label | ||||
| end | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|  | ||||
|         local label = player.gui.screen[current_time_label] | ||||
|  | ||||
|         if not label or not label.valid then | ||||
|             label = create_label(player) | ||||
|         end | ||||
|         set_location(player) | ||||
|         label.visible = false | ||||
|     end | ||||
| ) | ||||
|  | ||||
| -- Update the value each second | ||||
| Event.on_nth_tick( | ||||
|     60, | ||||
|     function() | ||||
|         local date = Server.get_current_date_with_time() | ||||
|         if not date then | ||||
|             date = '1969-01-01 00:00' | ||||
|         end | ||||
|  | ||||
|         local players = game.connected_players | ||||
|         for i = 1, #players do | ||||
|             local player = players[i] | ||||
|             local label = player.gui.screen[current_time_label] | ||||
|             if label and label.valid then | ||||
|                 label.caption = date | ||||
|                 set_location(player) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'server-date', | ||||
|     'Toggle to show the date', | ||||
|     function() | ||||
|         local player = game.player | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|  | ||||
|         if validate_player(player) then | ||||
|             if not secs then | ||||
|                 return player.print('Not running on Comfy backend.', Color.warning) | ||||
|             end | ||||
|  | ||||
|             local label = player.gui.screen[current_time_label] | ||||
|             if not label or not label.valid then | ||||
|                 label = create_label(player) | ||||
|             end | ||||
|  | ||||
|             if label.visible then | ||||
|                 label.visible = false | ||||
|                 player.print('Removed date-label.', Color.warning) | ||||
|             else | ||||
|                 label.visible = true | ||||
|                 set_location(player) | ||||
|                 player.print('Added date-label.', Color.success) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Gui.screen_to_bypass(current_time_label) | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_display_resolution_changed, | ||||
|     function(event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         set_location(player) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_display_scale_changed, | ||||
|     function(event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         set_location(player) | ||||
|     end | ||||
| ) | ||||
| @@ -1,5 +1,4 @@ | ||||
| require 'utils.datastore.server_ups_data' | ||||
| require 'utils.datastore.current_time_data' | ||||
| require 'utils.datastore.color_data' | ||||
| require 'utils.datastore.session_data' | ||||
| require 'utils.datastore.statistics' | ||||
|   | ||||
| @@ -10,6 +10,7 @@ local Utils = require 'utils.core' | ||||
| local table = require 'utils.table' | ||||
| local Gui = require 'utils.gui' | ||||
| local StatData = require 'utils.datastore.statistics' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| StatData.add_normalize('jailed', 'Jailed') | ||||
|  | ||||
| @@ -24,10 +25,10 @@ local votejail = {} | ||||
| local votefree = {} | ||||
| local revoked_permissions = {} | ||||
| local settings = { | ||||
|     playtime_for_vote = 77760000, -- 15 days | ||||
|     playtime_for_vote = 77760000,          -- 15 days | ||||
|     playtime_for_instant_jail = 362880000, -- 70 days | ||||
|     -- playtime_for_instant_jail = 103680000, -- 20 days | ||||
|     clear_voted_player = 36000, -- remove player from vote-tbl after 10 minutes | ||||
|     clear_voted_player = 36000,            -- remove player from vote-tbl after 10 minutes | ||||
|     clear_terms_tbl = 2000, | ||||
|     votejail_count = 5, | ||||
|     valid_surface = 'nauvis', | ||||
| @@ -64,7 +65,7 @@ Global.register( | ||||
|         terms_tbl = terms_tbl, | ||||
|         revoked_permissions = revoked_permissions | ||||
|     }, | ||||
|     function(t) | ||||
|     function (t) | ||||
|         jailed = t.jailed | ||||
|         votejail = t.votejail | ||||
|         votefree = t.votefree | ||||
| @@ -111,7 +112,7 @@ local function add_revoked(name, admin, reason) | ||||
|  | ||||
|         if not revoked_permissions[name] then | ||||
|             revoked_permissions[name] = true | ||||
|             set_data(revoked_permissions_set, name, {revoked = true, actor = admin, reason = reason, date = date}) | ||||
|             set_data(revoked_permissions_set, name, { revoked = true, actor = admin, reason = reason, date = date }) | ||||
|             return true | ||||
|         else | ||||
|             return false | ||||
| @@ -135,67 +136,67 @@ end | ||||
|  | ||||
| local clear_terms_tbl = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local player = data.player | ||||
|         if not player then | ||||
|             return | ||||
|         end | ||||
|         function (data) | ||||
|             local player = data.player | ||||
|             if not player then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         if terms_tbl[player] then | ||||
|             terms_tbl[player] = nil | ||||
|             return | ||||
|             if terms_tbl[player] then | ||||
|                 terms_tbl[player] = nil | ||||
|                 return | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| local play_alert_sound = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local name = data.name | ||||
|         if not name then | ||||
|             return | ||||
|         end | ||||
|         local player = game.get_player(name) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|         function (data) | ||||
|             local name = data.name | ||||
|             if not name then | ||||
|                 return | ||||
|             end | ||||
|             local player = game.get_player(name) | ||||
|             if not player or not player.valid then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         player.play_sound {path = 'utility/scenario_message', volume_modifier = 1} | ||||
|     end | ||||
| ) | ||||
|             player.play_sound { path = 'utility/scenario_message', volume_modifier = 1 } | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| local clear_jail_data_token = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local offender = data.offender | ||||
|         if not offender then | ||||
|             return | ||||
|         end | ||||
|         if votejail[offender] and votejail[offender].jailed then | ||||
|             return | ||||
|         end | ||||
|         function (data) | ||||
|             local offender = data.offender | ||||
|             if not offender then | ||||
|                 return | ||||
|             end | ||||
|             if votejail[offender] and votejail[offender].jailed then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         local msg_two = 'You have been cleared of all accusations because not enough players voted against you.' | ||||
|         Utils.print_to(offender, msg_two) | ||||
|         votejail[offender] = nil | ||||
|         votefree[offender] = nil | ||||
|     end | ||||
| ) | ||||
|             local msg_two = 'You have been cleared of all accusations because not enough players voted against you.' | ||||
|             Utils.print_to(offender, msg_two) | ||||
|             votejail[offender] = nil | ||||
|             votefree[offender] = nil | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| local clear_gui = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local player = data.player | ||||
|         if player and player.valid then | ||||
|             for _, child in pairs(player.gui.center.children) do | ||||
|                 child.destroy() | ||||
|             end | ||||
|             for _, child in pairs(player.gui.left.children) do | ||||
|                 child.destroy() | ||||
|         function (data) | ||||
|             local player = data.player | ||||
|             if player and player.valid then | ||||
|                 for _, child in pairs(player.gui.center.children) do | ||||
|                     child.destroy() | ||||
|                 end | ||||
|                 for _, child in pairs(player.gui.left.children) do | ||||
|                     child.destroy() | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| local function validate_playtime(player) | ||||
|     local tracker = Session.get_session_table() | ||||
| @@ -266,46 +267,46 @@ local function create_gulag_surface() | ||||
|         local walls = {} | ||||
|         local tiles = {} | ||||
|         pcall( | ||||
|             function() | ||||
|             function () | ||||
|                 surface = | ||||
|                     game.create_surface( | ||||
|                     'gulag', | ||||
|                     { | ||||
|                         autoplace_controls = { | ||||
|                             ['coal'] = {frequency = 23, size = 3, richness = 3}, | ||||
|                             ['stone'] = {frequency = 20, size = 3, richness = 3}, | ||||
|                             ['copper-ore'] = {frequency = 25, size = 3, richness = 3}, | ||||
|                             ['iron-ore'] = {frequency = 35, size = 3, richness = 3}, | ||||
|                             ['uranium-ore'] = {frequency = 20, size = 3, richness = 3}, | ||||
|                             ['crude-oil'] = {frequency = 80, size = 3, richness = 1}, | ||||
|                             ['trees'] = {frequency = 0.75, size = 2, richness = 0.1}, | ||||
|                             ['enemy-base'] = {frequency = 15, size = 0, richness = 1} | ||||
|                         }, | ||||
|                         cliff_settings = {cliff_elevation_0 = 1024, cliff_elevation_interval = 10, name = 'cliff'}, | ||||
|                         height = 64, | ||||
|                         width = 256, | ||||
|                         peaceful_mode = false, | ||||
|                         seed = 1337, | ||||
|                         starting_area = 'very-low', | ||||
|                         starting_points = {{x = 0, y = 0}}, | ||||
|                         terrain_segmentation = 'normal', | ||||
|                         water = 'normal' | ||||
|                     } | ||||
|                 ) | ||||
|                         'gulag', | ||||
|                         { | ||||
|                             autoplace_controls = { | ||||
|                                 ['coal'] = { frequency = 23, size = 3, richness = 3 }, | ||||
|                                 ['stone'] = { frequency = 20, size = 3, richness = 3 }, | ||||
|                                 ['copper-ore'] = { frequency = 25, size = 3, richness = 3 }, | ||||
|                                 ['iron-ore'] = { frequency = 35, size = 3, richness = 3 }, | ||||
|                                 ['uranium-ore'] = { frequency = 20, size = 3, richness = 3 }, | ||||
|                                 ['crude-oil'] = { frequency = 80, size = 3, richness = 1 }, | ||||
|                                 ['trees'] = { frequency = 0.75, size = 2, richness = 0.1 }, | ||||
|                                 ['enemy-base'] = { frequency = 15, size = 0, richness = 1 } | ||||
|                             }, | ||||
|                             cliff_settings = { cliff_elevation_0 = 1024, cliff_elevation_interval = 10, name = 'cliff' }, | ||||
|                             height = 64, | ||||
|                             width = 256, | ||||
|                             peaceful_mode = false, | ||||
|                             seed = 1337, | ||||
|                             starting_area = 'very-low', | ||||
|                             starting_points = { { x = 0, y = 0 } }, | ||||
|                             terrain_segmentation = 'normal', | ||||
|                             water = 'normal' | ||||
|                         } | ||||
|                     ) | ||||
|             end | ||||
|         ) | ||||
|         if not surface then | ||||
|             surface = game.create_surface('gulag', {width = 40, height = 40}) | ||||
|             surface = game.create_surface('gulag', { width = 40, height = 40 }) | ||||
|         end | ||||
|         surface.always_day = true | ||||
|         surface.request_to_generate_chunks({0, 0}, 9) | ||||
|         surface.request_to_generate_chunks({ 0, 0 }, 9) | ||||
|         surface.force_generate_chunk_requests() | ||||
|         local area = {left_top = {x = -128, y = -32}, right_bottom = {x = 128, y = 32}} | ||||
|         local area = { left_top = { x = -128, y = -32 }, right_bottom = { x = 128, y = 32 } } | ||||
|         for x = area.left_top.x, area.right_bottom.x, 1 do | ||||
|             for y = area.left_top.y, area.right_bottom.y, 1 do | ||||
|                 tiles[#tiles + 1] = {name = 'black-refined-concrete', position = {x = x, y = y}} | ||||
|                 tiles[#tiles + 1] = { name = 'black-refined-concrete', position = { x = x, y = y } } | ||||
|                 if x == area.left_top.x or x == area.right_bottom.x or y == area.left_top.y or y == area.right_bottom.y then | ||||
|                     walls[#walls + 1] = {name = 'stone-wall', force = 'neutral', position = {x = x, y = y}} | ||||
|                     walls[#walls + 1] = { name = 'stone-wall', force = 'neutral', position = { x = x, y = y } } | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
| @@ -319,8 +320,8 @@ local function create_gulag_surface() | ||||
|         rendering.draw_text { | ||||
|             text = 'The pit of despair ☹', | ||||
|             surface = surface, | ||||
|             target = {0, -50}, | ||||
|             color = {r = 0.98, g = 0.66, b = 0.22}, | ||||
|             target = { 0, -50 }, | ||||
|             color = { r = 0.98, g = 0.66, b = 0.22 }, | ||||
|             scale = 10, | ||||
|             font = 'heading-1', | ||||
|             alignment = 'center', | ||||
| @@ -346,7 +347,7 @@ local function teleport_player_to_gulag(player, action, mute) | ||||
|             p_data.locked = true | ||||
|             p_data.muted = mute or false | ||||
|         end | ||||
|         player.teleport(gulag.find_non_colliding_position('character', {0, 0}, 128, 1), gulag.name) | ||||
|         player.teleport(gulag.find_non_colliding_position('character', { 0, 0 }, 128, 1), gulag.name) | ||||
|         local data = { | ||||
|             player = player | ||||
|         } | ||||
| @@ -374,7 +375,7 @@ local function teleport_player_to_gulag(player, action, mute) | ||||
|         end | ||||
|  | ||||
|         p_group.add_player(player) | ||||
|         local pos = {x = p.x, y = p.y} | ||||
|         local pos = { x = p.x, y = p.y } | ||||
|         ---@diagnostic disable-next-line: missing-parameter | ||||
|         local get_tile = surface.get_tile(pos) | ||||
|         if get_tile.valid and get_tile.name == 'out-of-map' then | ||||
| @@ -555,10 +556,10 @@ local function vote_to_jail(player, offender, msg) | ||||
|     end | ||||
|  | ||||
|     if not votejail[offender] then | ||||
|         votejail[offender] = {index = 0, actor = player.name} | ||||
|         votejail[offender] = { index = 0, actor = player.name } | ||||
|         local message = player.name .. ' has started a vote to jail player ' .. offender | ||||
|         Utils.print_to(nil, message) | ||||
|         Task.set_timeout_in_ticks(settings.clear_voted_player, clear_jail_data_token, {offender = offender}) | ||||
|         Task.set_timeout_in_ticks(settings.clear_voted_player, clear_jail_data_token, { offender = offender }) | ||||
|     end | ||||
|  | ||||
|     if not votejail[offender][player.name] then | ||||
| @@ -583,7 +584,7 @@ local function vote_to_free(player, offender) | ||||
|     end | ||||
|  | ||||
|     if not votefree[offender] then | ||||
|         votefree[offender] = {index = 0, actor = player.name} | ||||
|         votefree[offender] = { index = 0, actor = player.name } | ||||
|         local message = player.name .. ' has started a vote to free player ' .. offender | ||||
|         Utils.print_to(nil, message) | ||||
|     end | ||||
| @@ -644,12 +645,12 @@ local function jail(player, offender, msg, raised, mute) | ||||
|  | ||||
|     local message = offender .. ' has been jailed by ' .. player .. '. Cause: ' .. msg | ||||
|  | ||||
|     jailed[offender] = {jailed = true, actor = player, reason = msg} | ||||
|     jailed[offender] = { jailed = true, actor = player, reason = msg } | ||||
|     if not raised then | ||||
|         set_data(jailed_data_set, offender, {jailed = true, actor = player, reason = msg, date = date}) | ||||
|         set_data(jailed_data_set, offender, { jailed = true, actor = player, reason = msg, date = date }) | ||||
|     end | ||||
|  | ||||
|     Event.raise(Public.events.on_player_jailed, {player_index = offender.index}) | ||||
|     Event.raise(Public.events.on_player_jailed, { player_index = offender.index }) | ||||
|  | ||||
|     StatData.get_data(to_jail_player.index):increase('jailed') | ||||
|  | ||||
| @@ -701,7 +702,7 @@ local function jail_temporary(player, offender, msg, mute) | ||||
|  | ||||
|     local message = offender.name .. ' has been temporary jailed by ' .. player.name .. '.' | ||||
|  | ||||
|     jailed[offender.name] = {jailed = true, actor = player.name, reason = msg, temporary = true} | ||||
|     jailed[offender.name] = { jailed = true, actor = player.name, reason = msg, temporary = true } | ||||
|  | ||||
|     Utils.print_to(nil, message) | ||||
|     local data = Server.build_embed_data() | ||||
| @@ -715,7 +716,7 @@ local function jail_temporary(player, offender, msg, mute) | ||||
|         votejail[offender.name].jailed = true | ||||
|     end | ||||
|  | ||||
|     Event.raise(Public.events.on_player_jailed, {player_index = offender.index}) | ||||
|     Event.raise(Public.events.on_player_jailed, { player_index = offender.index }) | ||||
|  | ||||
|     StatData.get_data(offender.index):increase('jailed') | ||||
|  | ||||
| @@ -723,7 +724,7 @@ local function jail_temporary(player, offender, msg, mute) | ||||
|  | ||||
|     draw_notice_frame(offender) | ||||
|  | ||||
|     Task.set_timeout_in_ticks(10800, release_player_from_temporary_prison_token, {offender_name = offender.name, actor_name = player.name}) | ||||
|     Task.set_timeout_in_ticks(10800, release_player_from_temporary_prison_token, { offender_name = offender.name, actor_name = player.name }) | ||||
|     return true | ||||
| end | ||||
|  | ||||
| @@ -744,7 +745,7 @@ local function free(player, offender) | ||||
|  | ||||
|     set_data(jailed_data_set, offender, nil) | ||||
|  | ||||
|     Event.raise(Public.events.on_player_unjailed, {player_index = offender.index}) | ||||
|     Event.raise(Public.events.on_player_unjailed, { player_index = offender.index }) | ||||
|  | ||||
|     Utils.print_to(nil, message) | ||||
|     local data = Server.build_embed_data() | ||||
| @@ -759,34 +760,34 @@ end | ||||
|  | ||||
| local is_jailed = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local key = data.key | ||||
|         local value = data.value | ||||
|         if value and value.jailed and value.reason then | ||||
|             jail('script', key, value.reason, true) | ||||
|         else | ||||
|             free('script', key) | ||||
|         function (data) | ||||
|             local key = data.key | ||||
|             local value = data.value | ||||
|             if value and value.jailed and value.reason then | ||||
|                 jail('script', key, value.reason, true) | ||||
|             else | ||||
|                 free('script', key) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| --! start gui handler | ||||
|  | ||||
| release_player_from_temporary_prison_token = | ||||
|     Token.register( | ||||
|     function(event) | ||||
|         local actor_name = event.actor_name | ||||
|         local offender_name = event.offender_name | ||||
|         function (event) | ||||
|             local actor_name = event.actor_name | ||||
|             local offender_name = event.offender_name | ||||
|  | ||||
|         if jailed[offender_name] and jailed[offender_name].temporary then | ||||
|             free('script', offender_name) | ||||
|             Utils.print_to(nil, module_name .. 'If you find someone abusing their jail permissions - report them to the admins of Comfy!') | ||||
|             if jailed[offender_name] and jailed[offender_name].temporary then | ||||
|                 free('script', offender_name) | ||||
|                 Utils.print_to(nil, module_name .. 'If you find someone abusing their jail permissions - report them to the admins of Comfy!') | ||||
|  | ||||
|             local actor = game.get_player(actor_name) | ||||
|             remove_action_needed(actor) | ||||
|                 local actor = game.get_player(actor_name) | ||||
|                 remove_action_needed(actor) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| local function remove_target_frame(target_frame) | ||||
|     Gui.remove_data_recursively(target_frame) | ||||
| @@ -806,12 +807,12 @@ local function draw_main_frame(player, offender) | ||||
|  | ||||
|     local warning_message = | ||||
|         concat { | ||||
|         '[font=heading-2]You have jailed player: [color=yellow]', | ||||
|         offender.name, | ||||
|         '\n[/color][/font]' | ||||
|     } | ||||
|             '[font=heading-2]You have jailed player: [color=yellow]', | ||||
|             offender.name, | ||||
|             '\n[/color][/font]' | ||||
|         } | ||||
|  | ||||
|     local info_warning_text = inside_table.add({type = 'label', caption = warning_message}) | ||||
|     local info_warning_text = inside_table.add({ type = 'label', caption = warning_message }) | ||||
|     local info_warning_text_style = info_warning_text.style | ||||
|     info_warning_text_style.single_line = false | ||||
|     info_warning_text_style.width = 470 | ||||
| @@ -824,14 +825,14 @@ local function draw_main_frame(player, offender) | ||||
|  | ||||
|     local abuse_message = | ||||
|         concat { | ||||
|         'Jailing is [color=red]NOT[/color] allowed to solve personal disputes, talk to each other instead of jailing!\n', | ||||
|         'Jail is only a temporary solution, the jailed offender will be released in less than one week automatically.\n', | ||||
|         'If the actions done by the offender was serious, report the offender to the admins on [color=yellow]https://getcomfy.eu/discord[/color]\n', | ||||
|         'Providing NO reason will free the offender after 3 minutes or if you close this window - note - this will log your actions to our admins.\n\n', | ||||
|         '[color=yellow]Explain why you jailed ' .. offender.name .. '[/color]' | ||||
|     } | ||||
|             'Jailing is [color=red]NOT[/color] allowed to solve personal disputes, talk to each other instead of jailing!\n', | ||||
|             'Jail is only a temporary solution, the jailed offender will be released in less than one week automatically.\n', | ||||
|             'If the actions done by the offender was serious, report the offender to the admins on [color=yellow]https://getcomfy.eu/discord[/color]\n', | ||||
|             'Providing NO reason will free the offender after 3 minutes or if you close this window - note - this will log your actions to our admins.\n\n', | ||||
|             '[color=yellow]Explain why you jailed ' .. offender.name .. '[/color]' | ||||
|         } | ||||
|  | ||||
|     local info_warning_text_extended = inside_table.add({type = 'label', caption = abuse_message}) | ||||
|     local info_warning_text_extended = inside_table.add({ type = 'label', caption = abuse_message }) | ||||
|     local info_warning_text_extended_style = info_warning_text_extended.style | ||||
|     info_warning_text_extended_style.single_line = false | ||||
|     info_warning_text_extended_style.font = 'heading-2' | ||||
| @@ -842,7 +843,7 @@ local function draw_main_frame(player, offender) | ||||
|     info_warning_text_extended_style.right_padding = 4 | ||||
|     info_warning_text_extended_style.bottom_padding = 4 | ||||
|  | ||||
|     local placeholder_text = inside_table.add({type = 'text-box', text = '', name = placeholder_jail_text_box}) | ||||
|     local placeholder_text = inside_table.add({ type = 'text-box', text = '', name = placeholder_jail_text_box }) | ||||
|     local placeholder_text_style = placeholder_text.style | ||||
|     placeholder_text_style.width = 470 | ||||
|     placeholder_text_style.height = 200 | ||||
| @@ -852,19 +853,19 @@ local function draw_main_frame(player, offender) | ||||
|     placeholder_text_style.horizontally_squashable = false | ||||
|     placeholder_text_style.vertically_squashable = false | ||||
|  | ||||
|     local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'}) | ||||
|     local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' }) | ||||
|  | ||||
|     local left_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local left_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     left_flow.style.horizontal_align = 'left' | ||||
|     left_flow.style.horizontally_stretchable = true | ||||
|  | ||||
|     local close_button = left_flow.add({type = 'button', name = discard_button_name, caption = 'Discard report'}) | ||||
|     local close_button = left_flow.add({ type = 'button', name = discard_button_name, caption = 'Discard report' }) | ||||
|     close_button.style = 'back_button' | ||||
|  | ||||
|     local right_flow = bottom_flow.add({type = 'flow'}) | ||||
|     local right_flow = bottom_flow.add({ type = 'flow' }) | ||||
|     right_flow.style.horizontal_align = 'right' | ||||
|  | ||||
|     local save_button = right_flow.add({type = 'button', name = save_button_name, caption = 'Save report'}) | ||||
|     local save_button = right_flow.add({ type = 'button', name = save_button_name, caption = 'Save report' }) | ||||
|     save_button.style = 'confirm_button' | ||||
|  | ||||
|     local data = { | ||||
| @@ -878,7 +879,7 @@ local function draw_main_frame(player, offender) | ||||
|     player.opened = main_frame | ||||
| end | ||||
|  | ||||
| remove_notice = function(player) | ||||
| remove_notice = function (player) | ||||
|     local screen = player.gui.screen | ||||
|     local notice = screen[notice_frame_name] | ||||
|  | ||||
| @@ -887,7 +888,7 @@ remove_notice = function(player) | ||||
|     end | ||||
| end | ||||
|  | ||||
| remove_action_needed = function(player) | ||||
| remove_action_needed = function (player) | ||||
|     local screen = player.gui.screen | ||||
|     local action_needed = screen[jail_frame_name] | ||||
|  | ||||
| @@ -896,7 +897,7 @@ remove_action_needed = function(player) | ||||
|     end | ||||
| end | ||||
|  | ||||
| draw_notice_frame = function(player) | ||||
| draw_notice_frame = function (player) | ||||
|     local main_frame, inside_table = Gui.add_main_frame_with_toolbar(player, 'screen', notice_frame_name, nil, nil, 'Notice', true, 2) | ||||
|  | ||||
|     if not main_frame or not inside_table then | ||||
| @@ -907,20 +908,20 @@ draw_notice_frame = function(player) | ||||
|     main_frame_style.width = 400 | ||||
|     main_frame.auto_center = true | ||||
|  | ||||
|     local content_flow = inside_table.add {type = 'flow', direction = 'horizontal'} | ||||
|     local content_flow = inside_table.add { type = 'flow', direction = 'horizontal' } | ||||
|     content_flow.style.top_padding = 16 | ||||
|     content_flow.style.bottom_padding = 16 | ||||
|     content_flow.style.left_padding = 24 | ||||
|     content_flow.style.right_padding = 24 | ||||
|     content_flow.style.horizontally_stretchable = false | ||||
|  | ||||
|     local sprite_flow = content_flow.add {type = 'flow'} | ||||
|     local sprite_flow = content_flow.add { type = 'flow' } | ||||
|     sprite_flow.style.vertical_align = 'center' | ||||
|     sprite_flow.style.vertically_stretchable = false | ||||
|  | ||||
|     sprite_flow.add {type = 'sprite', sprite = 'utility/warning_icon'} | ||||
|     sprite_flow.add { type = 'sprite', sprite = 'utility/warning_icon' } | ||||
|  | ||||
|     local label_flow = content_flow.add {type = 'flow'} | ||||
|     local label_flow = content_flow.add { type = 'flow' } | ||||
|     label_flow.style.horizontal_align = 'left' | ||||
|     label_flow.style.top_padding = 10 | ||||
|     label_flow.style.left_padding = 24 | ||||
| @@ -933,7 +934,7 @@ draw_notice_frame = function(player) | ||||
|     end | ||||
|  | ||||
|     label_flow.style.horizontally_stretchable = false | ||||
|     local label = label_flow.add {type = 'label', caption = warning_message} | ||||
|     local label = label_flow.add { type = 'label', caption = warning_message } | ||||
|     label.style.single_line = false | ||||
|  | ||||
|     player.opened = main_frame | ||||
| @@ -943,19 +944,19 @@ end | ||||
|  | ||||
| local update_jailed = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local key = data.key | ||||
|         local value = data.value or false | ||||
|         local player = data.player or 'script' | ||||
|         local message = data.message | ||||
|         local mute = data.mute or false | ||||
|         if value then | ||||
|             jail(player, key, message, nil, mute) | ||||
|         else | ||||
|             free(player, key) | ||||
|         function (data) | ||||
|             local key = data.key | ||||
|             local value = data.value or false | ||||
|             local player = data.player or 'script' | ||||
|             local message = data.message | ||||
|             local mute = data.mute or false | ||||
|             if value then | ||||
|                 jail(player, key, message, nil, mute) | ||||
|             else | ||||
|                 free(player, key) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| --- Tries to get data from the webpanel and updates the local table with values. | ||||
| -- @param data_set player token | ||||
| @@ -1058,20 +1059,20 @@ end | ||||
| --- Writes the data called back from the server into the revoked_permissions table, clearing any previous entries | ||||
| local sync_revoked_permissions_callback = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         if not data then | ||||
|             return | ||||
|         end | ||||
|         if not data.entries then | ||||
|             return | ||||
|         end | ||||
|         function (data) | ||||
|             if not data then | ||||
|                 return | ||||
|             end | ||||
|             if not data.entries then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         table.clear_table(revoked_permissions) | ||||
|         for k, v in pairs(data.entries) do | ||||
|             revoked_permissions[k] = v | ||||
|             table.clear_table(revoked_permissions) | ||||
|             for k, v in pairs(data.entries) do | ||||
|                 revoked_permissions[k] = v | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| --- Signals the server to retrieve the revoked_permissions dataset | ||||
| function Public.sync_revoked_permissions() | ||||
| @@ -1105,7 +1106,7 @@ end | ||||
|  | ||||
| Server.on_data_set_changed( | ||||
|     jailed_data_set, | ||||
|     function(data) | ||||
|     function (data) | ||||
|         if not data then | ||||
|             return | ||||
|         end | ||||
| @@ -1122,7 +1123,7 @@ Server.on_data_set_changed( | ||||
|  | ||||
| Server.on_data_set_changed( | ||||
|     revoked_permissions_set, | ||||
|     function(data) | ||||
|     function (data) | ||||
|         if not data then | ||||
|             return | ||||
|         end | ||||
| @@ -1131,97 +1132,44 @@ Server.on_data_set_changed( | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'jail', | ||||
|     'Sends the player to gulag! Valid arguments are:\n/jail <LuaPlayer>', | ||||
|     function() | ||||
|     end | ||||
| ) | ||||
| Commands.new('jail', 'Sends the player to gulag.') | ||||
|     :add_parameter('offender', false, 'player') | ||||
|     :callback(function () | ||||
|     end) | ||||
|  | ||||
| commands.add_command( | ||||
|     'free', | ||||
|     'Brings back the player from gulag.', | ||||
|     function() | ||||
|     end | ||||
| ) | ||||
| Commands.new('free', 'Brings back the player from gulag.') | ||||
|     :add_parameter('offender', false, 'player') | ||||
|     :callback(function () | ||||
|     end) | ||||
|  | ||||
| commands.add_command( | ||||
|     'toggle_jail_permission', | ||||
|     'Usable only for admins - controls who may use jail commands!', | ||||
|     function(cmd) | ||||
|         local name | ||||
|         local player = game.player | ||||
|  | ||||
|         if not player or not player.valid then | ||||
|             name = 'Server' | ||||
|         else | ||||
|             name = player.name | ||||
|  | ||||
|             if not player.admin then | ||||
|                 return | ||||
|             end | ||||
| Commands.new('toggle_jail_permission', 'Usable only for admins - controls who may use jail commands!') | ||||
|     :require_backend() | ||||
|     :add_parameter('target-player', false, 'player') | ||||
|     :add_parameter('reason', false, 'string') | ||||
|     :callback(function (player, target, reason) | ||||
|         if is_revoked(target.name) then | ||||
|             remove_revoked(target.name) | ||||
|             Utils.print_to(player, target.name .. ' can now utilize jail commands once again!') | ||||
|             return true | ||||
|         end | ||||
|  | ||||
|         local param = cmd.parameter | ||||
|  | ||||
|         local t_player | ||||
|         local revoke_reason | ||||
|         local revoke_player | ||||
|         local str = '' | ||||
|  | ||||
|         if not param then | ||||
|             return Utils.print_to(player, 'Both player and reason is needed!') | ||||
|         if reason and string.len(reason) <= 0 then | ||||
|             Utils.print_to(player, 'No valid reason was given.') | ||||
|             return false | ||||
|         end | ||||
|  | ||||
|         local t = {} | ||||
|         for i in string.gmatch(param, '%S+') do | ||||
|             table.insert(t, i) | ||||
|         if reason and string.len(reason) <= 10 then | ||||
|             Utils.print_to(player, 'Reason is too short.') | ||||
|             return false | ||||
|         end | ||||
|  | ||||
|         t_player = t[1] | ||||
|         add_revoked(target.name, player.name, reason) | ||||
|         Utils.print_to(player, target.name .. ' is now forbidden from utilizing jail commands!') | ||||
|     end) | ||||
|  | ||||
|         for i = 2, #t do | ||||
|             str = str .. t[i] .. ' ' | ||||
|             revoke_reason = str | ||||
|         end | ||||
|  | ||||
|         if game.get_player(t_player) then | ||||
|             revoke_player = game.get_player(t_player) | ||||
|         else | ||||
|             return Utils.print_to(player, 'No player was provided.') | ||||
|         end | ||||
|  | ||||
|         if not revoke_player then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if is_revoked(revoke_player.name) then | ||||
|             remove_revoked(revoke_player.name) | ||||
|             Utils.print_to(player, revoke_player.name .. ' can now utilize jail commands once again!') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if revoke_reason then | ||||
|             if revoke_reason and string.len(revoke_reason) <= 0 then | ||||
|                 Utils.print_to(player, 'No valid reason was given.') | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             if revoke_reason and string.len(revoke_reason) <= 10 then | ||||
|                 Utils.print_to(player, 'Reason is too short.') | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             add_revoked(revoke_player.name, name, revoke_reason) | ||||
|             Utils.print_to(player, revoke_player.name .. ' is now forbidden from utilizing jail commands!') | ||||
|         else | ||||
|             Utils.print_to(player, 'No message was provided') | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Event.on_init( | ||||
|     function() | ||||
|     function () | ||||
|         get_gulag_permission_group() | ||||
|         create_gulag_surface() | ||||
|     end | ||||
| @@ -1229,14 +1177,14 @@ Event.on_init( | ||||
|  | ||||
| Event.add( | ||||
|     Server.events.on_server_started, | ||||
|     function() | ||||
|     function () | ||||
|         Public.sync_revoked_permissions() | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_console_command, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local cmd = event.command | ||||
|         if not valid_commands[cmd] then | ||||
|             return | ||||
| @@ -1293,11 +1241,11 @@ Event.add( | ||||
|                         Utils.warning(player, "Jailing someone because they're afk or other stupid reasons is NOT valid!") | ||||
|                         Utils.warning(player, 'Run this command again to if you really want to do this!') | ||||
|                         for _ = 1, 4 do | ||||
|                             Task.set_timeout_in_ticks(delay, play_alert_sound, {name = player.name}) | ||||
|                             Task.set_timeout_in_ticks(delay, play_alert_sound, { name = player.name }) | ||||
|                             delay = delay + 30 | ||||
|                         end | ||||
|                         terms_tbl[player.name] = true | ||||
|                         Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, {player = player.name}) | ||||
|                         Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, { player = player.name }) | ||||
|                         return | ||||
|                     end | ||||
|  | ||||
| @@ -1328,11 +1276,11 @@ Event.add( | ||||
|                         Utils.warning(player, "Jailing someone because they're afk or other stupid reasons is NOT valid!") | ||||
|                         Utils.warning(player, 'Run this command again to if you really want to do this!') | ||||
|                         for _ = 1, 4 do | ||||
|                             Task.set_timeout_in_ticks(delay, play_alert_sound, {name = player.name}) | ||||
|                             Task.set_timeout_in_ticks(delay, play_alert_sound, { name = player.name }) | ||||
|                             delay = delay + 30 | ||||
|                         end | ||||
|                         terms_tbl[player.name] = true | ||||
|                         Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, {player = player.name}) | ||||
|                         Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, { player = player.name }) | ||||
|                         return | ||||
|                     end | ||||
|  | ||||
| @@ -1373,7 +1321,7 @@ Event.add( | ||||
|                     print(module_name .. 'Abusing the jail command will lead to revoked permissions. Jailing someone in case of disagreement is _NEVER_ OK!') | ||||
|                     print(module_name .. 'Run this command again to if you really want to do this!') | ||||
|                     terms_tbl['script'] = true | ||||
|                     Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, {player = 'script'}) | ||||
|                     Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, { player = 'script' }) | ||||
|                     return | ||||
|                 end | ||||
|  | ||||
| @@ -1391,7 +1339,7 @@ Event.add( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| @@ -1423,7 +1371,7 @@ Event.add( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_changed_surface, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| @@ -1446,7 +1394,7 @@ Event.add( | ||||
|  | ||||
| Gui.on_text_changed( | ||||
|     placeholder_jail_text_box, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = event.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| @@ -1475,7 +1423,7 @@ Gui.on_text_changed( | ||||
|  | ||||
| Gui.on_click( | ||||
|     save_button_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = event.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| @@ -1500,7 +1448,7 @@ Gui.on_click( | ||||
|                 return Utils.print_to(player, module_name .. 'Reason is too short. Explain thoroughly why you jailed ' .. offender .. '!') | ||||
|             end | ||||
|  | ||||
|             set_data(jailed_data_set, offender, {jailed = true, actor = player.name, reason = jailed[offender].reason, date = date}) | ||||
|             set_data(jailed_data_set, offender, { jailed = true, actor = player.name, reason = jailed[offender].reason, date = date }) | ||||
|         end | ||||
|  | ||||
|         Utils.print_to(player, module_name .. 'Jail data has been submitted!') | ||||
| @@ -1520,7 +1468,7 @@ Gui.on_click( | ||||
|  | ||||
| Gui.on_click( | ||||
|     discard_button_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = event.player | ||||
|         local screen = player.gui.screen | ||||
|         local frame = screen[jail_frame_name] | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| -- created by Gerkiz for ComfyFactorio | ||||
| local Token = require 'utils.token' | ||||
| local Color = require 'utils.color_presets' | ||||
| local Server = require 'utils.server' | ||||
| local Event = require 'utils.event' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local message_dataset = 'regulars' | ||||
| local set_data = Server.set_data | ||||
| @@ -12,18 +12,18 @@ local Public = {} | ||||
|  | ||||
| local fetch = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local key = data.key | ||||
|         local value = data.value | ||||
|         local player = game.players[key] | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         function (data) | ||||
|             local key = data.key | ||||
|             local value = data.value | ||||
|             local player = game.players[key] | ||||
|             if not player or not player.valid then | ||||
|                 return | ||||
|             end | ||||
|             if type(value) == 'table' then | ||||
|                 game.print('>> ' .. player.name .. ' << ' .. value.msg, value.color) -- we want the player name to be printed. | ||||
|             end | ||||
|         end | ||||
|         if type(value) == 'table' then | ||||
|             game.print('>> ' .. player.name .. ' << ' .. value.msg, value.color) -- we want the player name to be printed. | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| --- Tries to get data from the webpanel and applies the value to the player. | ||||
| -- @param data_set player token | ||||
| @@ -40,53 +40,36 @@ function Public.fetch(key) | ||||
|     end | ||||
| end | ||||
|  | ||||
| commands.add_command( | ||||
|     'save-message', | ||||
|     'Sets your custom join message. "{name}" will be replaced with your username', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|         if not secs then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local param = cmd.parameter | ||||
|         if param then | ||||
|             if param == '' or param == 'Name' then | ||||
|                 return player.print('You did not specify a message.', Color.warning) | ||||
| Commands.new('save-message', 'Sets your custom join message. "{name}" will be replaced with your username.') | ||||
|     :require_backend() | ||||
|     :add_parameter('message', false, 'string') | ||||
|     :callback( | ||||
|         function (player, message) | ||||
|             if message == '' or message == 'Name' then | ||||
|                 player.print('You did not specify a message.') | ||||
|                 return false | ||||
|             end | ||||
|             if string.len(param) > 64 then | ||||
|                 return player.print('Message is too long. 64 characters maximum.', {r = 0.90, g = 0.0, b = 0.0}) | ||||
|             if string.len(message) > 64 then | ||||
|                 player.print('Message is too long. 64 characters maximum.') | ||||
|                 return false | ||||
|             end | ||||
|             set_data(message_dataset, player.name, {msg = param, color = player.color}) | ||||
|             player.print('You message has been saved.', Color.success) | ||||
|         else | ||||
|             player.print('You did not specify a message.', Color.warning) | ||||
|             set_data(message_dataset, player.name, { msg = message, color = player.color }) | ||||
|             player.print('You message has been saved.') | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'remove-message', | ||||
|     'Removes your custom join message.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| Commands.new('remove-message', 'Removes your custom join message.') | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             set_data(message_dataset, player.name, nil) | ||||
|             player.print('Your message has been removed.') | ||||
|         end | ||||
|  | ||||
|         set_data(message_dataset, player.name, nil) | ||||
|         player.print('Your message has been removed.', Color.success) | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| -- created by Gerkiz for ComfyFactorio | ||||
| local Token = require 'utils.token' | ||||
| local Color = require 'utils.color_presets' | ||||
| local Server = require 'utils.server' | ||||
| local Event = require 'utils.event' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local tag_dataset = 'tags' | ||||
| local set_data = Server.set_data | ||||
| @@ -12,25 +12,25 @@ local Public = {} | ||||
|  | ||||
| local fetch = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         if not data then | ||||
|             return | ||||
|         end | ||||
|         function (data) | ||||
|             if not data then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         local key = data.key | ||||
|         local value = data.value | ||||
|         local player = game.players[key] | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|             local key = data.key | ||||
|             local value = data.value | ||||
|             local player = game.players[key] | ||||
|             if not player or not player.valid then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         if type(value) == 'string' then | ||||
|             player.tag = '[' .. value .. ']' | ||||
|             if type(value) == 'string' then | ||||
|                 player.tag = '[' .. value .. ']' | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| local alphanumeric = function(str) | ||||
| local alphanumeric = function (str) | ||||
|     return (string.match(str, '[^%w]') ~= nil) | ||||
| end | ||||
|  | ||||
| @@ -45,63 +45,44 @@ function Public.fetch(key) | ||||
|     end | ||||
| end | ||||
|  | ||||
| commands.add_command( | ||||
|     'save-tag', | ||||
|     'Sets your custom tag that is persistent.', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|         if not secs then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local param = cmd.parameter | ||||
|  | ||||
|         if param then | ||||
|             if alphanumeric(param) then | ||||
|                 player.print('Tag is not valid.', {r = 0.90, g = 0.0, b = 0.0}) | ||||
|                 return | ||||
| Commands.new('save-tag', 'Sets your custom tag that is persistent.') | ||||
|     :add_parameter('tag', false, 'The tag you want to set.') | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player, tag) | ||||
|             if alphanumeric(tag) then | ||||
|                 player.print('Tag is not valid.') | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
|             if param == '' or param == 'Name' then | ||||
|                 return player.print('You did not specify a tag.', Color.warning) | ||||
|             if tag == '' or tag == 'Name' then | ||||
|                 player.print('You did not specify a tag.') | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
|             if string.len(param) > 32 then | ||||
|                 player.print('Tag is too long. 64 characters maximum.', {r = 0.90, g = 0.0, b = 0.0}) | ||||
|                 return | ||||
|             if string.len(tag) > 32 then | ||||
|                 player.print('Tag is too long. 64 characters maximum.') | ||||
|                 return false | ||||
|             end | ||||
|  | ||||
|             set_data(tag_dataset, player.name, param) | ||||
|             player.tag = '[' .. param .. ']' | ||||
|             player.print('Your tag has been saved.', Color.success) | ||||
|         else | ||||
|             player.print('You did not specify a tag.', Color.warning) | ||||
|             set_data(tag_dataset, player.name, tag) | ||||
|             player.tag = '[' .. tag .. ']' | ||||
|             player.print('Your tag has been saved.') | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'remove-tag', | ||||
|     'Removes your custom tag.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| Commands.new('remove-tag', 'Removes your custom tag.') | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             set_data(tag_dataset, player.name, nil) | ||||
|             player.print('Your tag has been removed.') | ||||
|         end | ||||
|  | ||||
|         set_data(tag_dataset, player.name, nil) | ||||
|         player.print('Your tag has been removed.', Color.success) | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|   | ||||
| @@ -6,6 +6,7 @@ local Server = require 'utils.server' | ||||
| local Event = require 'utils.event' | ||||
| local Global = require 'utils.global' | ||||
| local Core = require 'utils.core' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local quickbar_dataset = 'quickbar' | ||||
| local quickbar_dataset_modded = 'quickbar_modded' | ||||
| @@ -28,7 +29,7 @@ local ignored_items = { | ||||
|  | ||||
| Global.register( | ||||
|     this, | ||||
|     function(t) | ||||
|     function (t) | ||||
|         this = t | ||||
|     end | ||||
| ) | ||||
| @@ -40,7 +41,7 @@ local function apply_stash(player) | ||||
|     if stash then | ||||
|         for i, slot in pairs(stash) do | ||||
|             if slot and slot.name then | ||||
|                 player.set_personal_logistic_slot(i, {name = slot.name, min = slot.min, max = slot.max}) | ||||
|                 player.set_personal_logistic_slot(i, { name = slot.name, min = slot.min, max = slot.max }) | ||||
|             end | ||||
|         end | ||||
|         this.logistics[player.name] = nil | ||||
| @@ -49,49 +50,49 @@ end | ||||
|  | ||||
| local fetch_quickbar = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local key = data.key | ||||
|         local value = data.value | ||||
|         local player = game.players[key] | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|         if value then | ||||
|             for i, slot in pairs(value) do | ||||
|                 if slot and slot ~= '' then | ||||
|                     player.set_quick_bar_slot(i, slot) | ||||
|                 end | ||||
|         function (data) | ||||
|             local key = data.key | ||||
|             local value = data.value | ||||
|             local player = game.players[key] | ||||
|             if not player or not player.valid then | ||||
|                 return | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| local fetch_logistics = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local key = data.key | ||||
|         local value = data.value | ||||
|         local player = game.players[key] | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|         local tech = player.force.technologies['logistic-robotics'].researched | ||||
|         if value then | ||||
|             for i, slot in pairs(value) do | ||||
|                 if slot and slot.name then | ||||
|                     if tech then | ||||
|                         player.set_personal_logistic_slot(i, {name = slot.name, min = slot.min, max = slot.max}) | ||||
|                     else | ||||
|                         if not this.logistics[player.name] then | ||||
|                             this.logistics[player.name] = {} | ||||
|                         end | ||||
|                         this.logistics[player.name][i] = {name = slot.name, min = slot.min, max = slot.max} | ||||
|             if value then | ||||
|                 for i, slot in pairs(value) do | ||||
|                     if slot and slot ~= '' then | ||||
|                         player.set_quick_bar_slot(i, slot) | ||||
|                     end | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| local fetch_logistics = | ||||
|     Token.register( | ||||
|         function (data) | ||||
|             local key = data.key | ||||
|             local value = data.value | ||||
|             local player = game.players[key] | ||||
|             if not player or not player.valid then | ||||
|                 return | ||||
|             end | ||||
|             local tech = player.force.technologies['logistic-robotics'].researched | ||||
|             if value then | ||||
|                 for i, slot in pairs(value) do | ||||
|                     if slot and slot.name then | ||||
|                         if tech then | ||||
|                             player.set_personal_logistic_slot(i, { name = slot.name, min = slot.min, max = slot.max }) | ||||
|                         else | ||||
|                             if not this.logistics[player.name] then | ||||
|                                 this.logistics[player.name] = {} | ||||
|                             end | ||||
|                             this.logistics[player.name][i] = { name = slot.name, min = slot.min, max = slot.max } | ||||
|                         end | ||||
|                     end | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| --- Tries to get data from the webpanel and applies the value to the player. | ||||
| -- @param LuaPlayer | ||||
| @@ -156,7 +157,7 @@ function Public.save_logistics(player) | ||||
|     for i = 1, 400 do | ||||
|         local slot = player.get_personal_logistic_slot(i) | ||||
|         if slot and slot.name then | ||||
|             slots[i] = {name = slot.name, min = slot.min, max = slot.max} | ||||
|             slots[i] = { name = slot.name, min = slot.min, max = slot.max } | ||||
|         end | ||||
|     end | ||||
|     if next(slots) then | ||||
| @@ -200,82 +201,51 @@ local save_logistics = Public.save_logistics | ||||
| local remove_quickbar = Public.remove_quickbar | ||||
| local remove_logistics = Public.remove_logistics | ||||
|  | ||||
| commands.add_command( | ||||
|     'save-quickbar', | ||||
|     'Save your personal quickbar preset so it´s always the same.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| Commands.new('save-quickbar', 'Save your personal quickbar preset so it´s always the same.') | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             save_quickbar(player) | ||||
|             player.print('Quickbar saved.') | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|         if not secs then | ||||
|             return | ||||
| Commands.new('save-logistics', 'Save your personal logistics preset so it´s always the same.') | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             local success, _ = pcall(save_logistics, player) | ||||
|             player.print('Notice: only the first 400 slots are saved.', Color.warning) | ||||
|             if not success then | ||||
|                 player.print('An error occured while trying to save your logistics slots.', Color.warning) | ||||
|                 return false | ||||
|             end | ||||
|             player.print('Logistics saved.') | ||||
|         end | ||||
|         save_quickbar(player) | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'save-logistics', | ||||
|     'Save your personal logistics preset so it´s always the same.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| Commands.new('remove-quickbar', 'Removes your personal quickbar preset from the datastore.') | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             remove_quickbar(player) | ||||
|             player.print('Quickbar removed.') | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|         if not secs then | ||||
|             return | ||||
| Commands.new('remove-logistics', 'Removes your personal logistics preset from the datastore.') | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             remove_logistics(player) | ||||
|             player.print('Logistics removed.') | ||||
|         end | ||||
|         local success, _ = pcall(save_logistics, player) | ||||
|         player.print('Notice: only the first 400 slots are saved.', Color.warning) | ||||
|         if not success then | ||||
|             player.print('An error occured while trying to save your logistics slots.', Color.warning) | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'remove-quickbar', | ||||
|     'Removes your personal quickbar preset from the datastore.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|         local secs = Server.get_current_time() | ||||
|         if not secs then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         remove_quickbar(player) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'remove-logistics', | ||||
|     'Removes your personal logistics preset from the datastore.', | ||||
|     function() | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|         if not secs then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         remove_logistics(player) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| @@ -293,11 +263,11 @@ Event.add( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_research_finished, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local research = event.research | ||||
|         if research.name == 'logistic-robotics' then | ||||
|             Core.iter_connected_players( | ||||
|                 function(player) | ||||
|                 function (player) | ||||
|                     apply_stash(player) | ||||
|                 end | ||||
|             ) | ||||
|   | ||||
| @@ -2,20 +2,10 @@ | ||||
| local Server = require 'utils.server' | ||||
| local Event = require 'utils.event' | ||||
| local Gui = require 'utils.gui' | ||||
| local Color = require 'utils.color_presets' | ||||
| local Commands = require 'utils.commands' | ||||
|  | ||||
| local ups_label = 'ups_label' | ||||
|  | ||||
| local function validate_player(player) | ||||
|     if not player then | ||||
|         return false | ||||
|     end | ||||
|     if not player.valid then | ||||
|         return false | ||||
|     end | ||||
|     return true | ||||
| end | ||||
|  | ||||
| local function set_location(player) | ||||
|     local gui = player.gui | ||||
|     local label = gui.screen[ups_label] | ||||
| @@ -24,7 +14,7 @@ local function set_location(player) | ||||
|     end | ||||
|     local res = player.display_resolution | ||||
|     local uis = player.display_scale | ||||
|     label.location = {x = res.width - 423 * uis, y = 30 * uis} | ||||
|     label.location = { x = res.width - 423 * uis, y = 30 * uis } | ||||
| end | ||||
|  | ||||
| local function create_label(player) | ||||
| @@ -33,12 +23,12 @@ local function create_label(player) | ||||
|  | ||||
|     local label = | ||||
|         player.gui.screen.add( | ||||
|         { | ||||
|             type = 'label', | ||||
|             name = ups_label, | ||||
|             caption = sUPS | ||||
|         } | ||||
|     ) | ||||
|             { | ||||
|                 type = 'label', | ||||
|                 name = ups_label, | ||||
|                 caption = sUPS | ||||
|             } | ||||
|         ) | ||||
|     local style = label.style | ||||
|     style.font = 'default-game' | ||||
|     return label | ||||
| @@ -46,7 +36,7 @@ end | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|  | ||||
|         local label = player.gui.screen[ups_label] | ||||
| @@ -62,7 +52,7 @@ Event.add( | ||||
| -- Update the value each second | ||||
| Event.on_nth_tick( | ||||
|     60, | ||||
|     function() | ||||
|     function () | ||||
|         local ups = Server.get_ups() | ||||
|         local caption = 'SUPS = ' .. ups | ||||
|         local players = game.connected_players | ||||
| @@ -77,19 +67,10 @@ Event.on_nth_tick( | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'server-ups', | ||||
|     'Toggle the server UPS display!', | ||||
|     function() | ||||
|         local player = game.player | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|  | ||||
|         if validate_player(player) then | ||||
|             if not secs then | ||||
|                 return player.print('Not running on Comfy backend.', Color.warning) | ||||
|             end | ||||
|  | ||||
| Commands.new('server-ups', 'Toggle the server UPS display!') | ||||
|     :require_backend() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             local label = player.gui.screen[ups_label] | ||||
|             if not label or not label.valid then | ||||
|                 label = create_label(player) | ||||
| @@ -97,21 +78,20 @@ commands.add_command( | ||||
|  | ||||
|             if label.visible then | ||||
|                 label.visible = false | ||||
|                 player.print('Removed Server-UPS label.', Color.warning) | ||||
|                 player.print('Removed Server-UPS label.') | ||||
|             else | ||||
|                 label.visible = true | ||||
|                 set_location(player) | ||||
|                 player.print('Added Server-UPS label.', Color.success) | ||||
|                 player.print('Added Server-UPS label.') | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| Gui.screen_to_bypass(ups_label) | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_display_resolution_changed, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         set_location(player) | ||||
|     end | ||||
| @@ -119,7 +99,7 @@ Event.add( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_display_scale_changed, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         set_location(player) | ||||
|     end | ||||
|   | ||||
| @@ -32,7 +32,7 @@ Global.register( | ||||
|         trusted = trusted, | ||||
|         settings = settings | ||||
|     }, | ||||
|     function(tbl) | ||||
|     function (tbl) | ||||
|         session = tbl.session | ||||
|         online_track = tbl.online_track | ||||
|         trusted = tbl.trusted | ||||
| @@ -48,120 +48,120 @@ local Public = { | ||||
|  | ||||
| local try_download_data_token = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local player_index = data.key | ||||
|         local value = data.value | ||||
|         if value then | ||||
|             session[player_index] = value | ||||
|             if value > settings.trusted_value then | ||||
|                 trusted[player_index] = true | ||||
|         function (data) | ||||
|             local player_index = data.key | ||||
|             local value = data.value | ||||
|             if value then | ||||
|                 session[player_index] = value | ||||
|                 if value > settings.trusted_value then | ||||
|                     trusted[player_index] = true | ||||
|                 end | ||||
|             else | ||||
|                 local player = game.get_player(player_index) | ||||
|                 if not player or not player.valid then | ||||
|                     return | ||||
|                 end | ||||
|                 session[player_index] = 0 | ||||
|                 trusted[player_index] = false | ||||
|                 -- we don't want to clutter the database with players less than 10 minutes played. | ||||
|                 if player.online_time >= settings.required_only_time_to_save_time then | ||||
|                     set_data(session_data_set, player_index, session[player_index]) | ||||
|                 end | ||||
|             end | ||||
|         else | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| local try_upload_data_token = | ||||
|     Token.register( | ||||
|         function (data) | ||||
|             local player_index = data.key | ||||
|             if not player_index then | ||||
|                 return | ||||
|             end | ||||
|             local value = data.value | ||||
|             local player = game.get_player(player_index) | ||||
|             if not player or not player.valid then | ||||
|                 return | ||||
|             end | ||||
|             session[player_index] = 0 | ||||
|             trusted[player_index] = false | ||||
|             -- we don't want to clutter the database with players less than 10 minutes played. | ||||
|             if player.online_time >= settings.required_only_time_to_save_time then | ||||
|                 set_data(session_data_set, player_index, session[player_index]) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| local try_upload_data_token = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local player_index = data.key | ||||
|         if not player_index then | ||||
|             return | ||||
|         end | ||||
|         local value = data.value | ||||
|         local player = game.get_player(player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if value then | ||||
|             -- we don't want to clutter the database with players less than 10 minutes played. | ||||
|             if player.online_time <= settings.required_only_time_to_save_time then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             local old_time_ingame = value | ||||
|  | ||||
|             if not online_track[player_index] then | ||||
|                 online_track[player_index] = 0 | ||||
|             end | ||||
|  | ||||
|             if online_track[player_index] > player.online_time then | ||||
|                 -- instance has been reset but scenario owner did not clear the player. | ||||
|                 -- so we clear it here and return. | ||||
|                 online_track[player_index] = 0 | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             local new_time = old_time_ingame + player.online_time - online_track[player_index] | ||||
|             if new_time <= 0 then | ||||
|                 new_time = old_time_ingame + player.online_time | ||||
|                 online_track[player_index] = 0 | ||||
|                 print('[ERROR] ' .. player_index .. ' had new time set as negative value: ' .. new_time) | ||||
|                 return | ||||
|             end | ||||
|             if new_time > settings.trusted_value then | ||||
|                 trusted[player_index] = true | ||||
|             end | ||||
|             set_data(session_data_set, player_index, new_time) | ||||
|             session[player_index] = new_time | ||||
|             online_track[player_index] = player.online_time | ||||
|         else | ||||
|             if player.online_time >= settings.required_only_time_to_save_time then | ||||
|                 if not session[player_index] then | ||||
|                     session[player_index] = 0 | ||||
|             if value then | ||||
|                 -- we don't want to clutter the database with players less than 10 minutes played. | ||||
|                 if player.online_time <= settings.required_only_time_to_save_time then | ||||
|                     return | ||||
|                 end | ||||
|  | ||||
|                 local old_time_ingame = value | ||||
|  | ||||
|                 if not online_track[player_index] then | ||||
|                     online_track[player_index] = 0 | ||||
|                 end | ||||
|  | ||||
|                 if online_track[player_index] > player.online_time then | ||||
|                     -- instance has been reset but scenario owner did not clear the player. | ||||
|                     -- so we clear it here and return. | ||||
|                     online_track[player_index] = 0 | ||||
|                     return | ||||
|                 end | ||||
|  | ||||
|                 local new_time = old_time_ingame + player.online_time - online_track[player_index] | ||||
|                 if new_time <= 0 then | ||||
|                     new_time = old_time_ingame + player.online_time | ||||
|                     online_track[player_index] = 0 | ||||
|                     print('[ERROR] ' .. player_index .. ' had new time set as negative value: ' .. new_time) | ||||
|                     return | ||||
|                 end | ||||
|                 if new_time > settings.trusted_value then | ||||
|                     trusted[player_index] = true | ||||
|                 end | ||||
|                 set_data(session_data_set, player_index, new_time) | ||||
|                 session[player_index] = new_time | ||||
|                 online_track[player_index] = player.online_time | ||||
|             else | ||||
|                 if player.online_time >= settings.required_only_time_to_save_time then | ||||
|                     if not session[player_index] then | ||||
|                         session[player_index] = 0 | ||||
|                     end | ||||
|                     set_data(session_data_set, player_index, session[player_index]) | ||||
|                 end | ||||
|                 set_data(session_data_set, player_index, session[player_index]) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| local get_total_playtime_token = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         if not data then | ||||
|             return | ||||
|         end | ||||
|         if not data.to_print then | ||||
|             return | ||||
|         end | ||||
|         function (data) | ||||
|             if not data then | ||||
|                 return | ||||
|             end | ||||
|             if not data.to_print then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         local player_index = data.key | ||||
|         local value = data.value | ||||
|         local to_print = data.to_print | ||||
|         local player = game.get_player(to_print) | ||||
|         if player and player.valid then | ||||
|             if player_index then | ||||
|                 if value then | ||||
|                     player.play_sound {path = 'utility/scenario_message', volume_modifier = 1} | ||||
|                     player.print('[color=blue]' .. player_index .. '[/color] has a total playtime of: ' .. Core.get_formatted_playtime(value)) | ||||
|                 else | ||||
|                     player.play_sound {path = 'utility/cannot_build', volume_modifier = 1} | ||||
|                     player.print('[color=red]' .. player_index .. '[/color] was not found.') | ||||
|             local player_index = data.key | ||||
|             local value = data.value | ||||
|             local to_print = data.to_print | ||||
|             local player = game.get_player(to_print) | ||||
|             if player and player.valid then | ||||
|                 if player_index then | ||||
|                     if value then | ||||
|                         player.play_sound { path = 'utility/scenario_message', volume_modifier = 1 } | ||||
|                         player.print('[color=blue]' .. player_index .. '[/color] has a total playtime of: ' .. Core.get_formatted_playtime(value)) | ||||
|                     else | ||||
|                         player.play_sound { path = 'utility/cannot_build', volume_modifier = 1 } | ||||
|                         player.print('[color=red]' .. player_index .. '[/color] was not found.') | ||||
|                     end | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| local nth_tick_token = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local player_name = data.name | ||||
|         Public.try_ul_data(player_name) | ||||
|     end | ||||
| ) | ||||
|         function (data) | ||||
|             local player_name = data.name | ||||
|             Public.try_ul_data(player_name) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| --- Uploads each connected players play time to the dataset | ||||
| local function upload_data() | ||||
| @@ -170,7 +170,7 @@ local function upload_data() | ||||
|     for i = 1, #players do | ||||
|         count = count + 10 | ||||
|         local player = players[i] | ||||
|         set_timeout_in_ticks(count, nth_tick_token, {name = player.name}) | ||||
|         set_timeout_in_ticks(count, nth_tick_token, { name = player.name }) | ||||
|     end | ||||
| end | ||||
|  | ||||
| @@ -283,7 +283,7 @@ function Public.get_trusted_table() | ||||
| end | ||||
|  | ||||
| --- Returns the table of trusted | ||||
| ---@param player LuaPlayer | ||||
| ---@param player? LuaPlayer | ||||
| ---@return table|boolean | ||||
| function Public.get_trusted_player(player) | ||||
|     return trusted and player and player.valid and trusted[player.name] or false | ||||
| @@ -306,7 +306,7 @@ function Public.set_untrusted_player(player) | ||||
| end | ||||
|  | ||||
| --- Returns the table of session | ||||
| ---@param player LuaPlayer | ||||
| ---@param player? LuaPlayer | ||||
| ---@return table|boolean | ||||
| function Public.get_session_player(player) | ||||
|     local secs = Server.get_current_time() | ||||
| @@ -349,7 +349,7 @@ end | ||||
| --- don't calculate the values wrong. | ||||
| Event.add( | ||||
|     Public.events.on_player_removed, | ||||
|     function() | ||||
|     function () | ||||
|         for name, _ in pairs(online_track) do | ||||
|             local player = game.get_player(name) | ||||
|             Public.clear_player(player) | ||||
| @@ -359,7 +359,7 @@ Event.add( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| @@ -371,7 +371,7 @@ Event.add( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_left_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| @@ -385,7 +385,7 @@ Event.on_nth_tick(settings.nth_tick, upload_data) | ||||
|  | ||||
| Server.on_data_set_changed( | ||||
|     session_data_set, | ||||
|     function(data) | ||||
|     function (data) | ||||
|         local player = game.get_player(data.key) | ||||
|         if player and player.valid then | ||||
|             session[data.key] = data.value | ||||
| @@ -400,27 +400,6 @@ Server.on_data_set_changed( | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'playtime', | ||||
|     'Fetches a player total playtime or nil.', | ||||
|     function(cmd) | ||||
|         local player = game.player | ||||
|         if not (player and player.valid) then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local p = player.print | ||||
|  | ||||
|         local param = cmd.parameter | ||||
|         if not param then | ||||
|             p('[ERROR] No player was provided.', Color.fail) | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         Public.get_and_print_to_player(player, param) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Public.upload_data = upload_data | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -1,31 +1,20 @@ | ||||
| local DebugView = require 'utils.debug.main_view' | ||||
| local Server = require 'utils.server' | ||||
| local Commands = require 'utils.commands' | ||||
| local Gui = require 'utils.gui' | ||||
|  | ||||
| commands.add_command( | ||||
|     'debug', | ||||
|     'Opens the debugger', | ||||
|     function(_) | ||||
|         local player = game.player | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| Commands.new('debug', 'Usable only for admins - opens the debugger!') | ||||
|     :require_admin() | ||||
|     :callback( | ||||
|         function (player) | ||||
|             local screen = player.gui.screen | ||||
|             local frame = screen[DebugView.main_frame_name] | ||||
|             if frame and frame.valid then | ||||
|                 Gui.destroy(frame) | ||||
|             end | ||||
|  | ||||
|             DebugView.open_debug(player) | ||||
|         end | ||||
|  | ||||
|         if not player.admin then | ||||
|             player.print('Only admins can use this command.') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local secs = Server.get_current_time() | ||||
|         local admins = Server.get_admins_data() | ||||
|  | ||||
|         if secs and not admins[player.name] then | ||||
|             player.print('Only admins can use this command.') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         DebugView.open_debug(player) | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| if _DEBUG then | ||||
|     local Model = require 'model' | ||||
| @@ -35,76 +24,50 @@ if _DEBUG then | ||||
|     local dump = Model.dump | ||||
|     local log = log | ||||
|  | ||||
|     commands.add_command( | ||||
|         'dump-log', | ||||
|         'Dumps value to log', | ||||
|         function(args) | ||||
|             local player = game.player | ||||
|             local p | ||||
|             if player then | ||||
|                 p = player.print | ||||
|                 if not player.admin then | ||||
|                     p('Only admins can use this command.') | ||||
|                     return | ||||
|     Commands.new('dump-log', 'Dumps value to log') | ||||
|         :require_admin() | ||||
|         :add_parameter('value', false, 'string') | ||||
|         :callback( | ||||
|             function (player, value) | ||||
|                 local func, err = loadstring('return ' .. value) | ||||
|  | ||||
|                 if not func then | ||||
|                     player.print(err) | ||||
|                     return false | ||||
|                 end | ||||
|             else | ||||
|                 p = player.print | ||||
|             end | ||||
|             if args.parameter == nil then | ||||
|                 return | ||||
|             end | ||||
|             local func, err = loadstring('return ' .. args.parameter) | ||||
|  | ||||
|             if not func then | ||||
|                 p(err) | ||||
|                 return | ||||
|             end | ||||
|                 local suc, v = pcall(func) | ||||
|  | ||||
|             local suc, value = pcall(func) | ||||
|  | ||||
|             if not suc then | ||||
|                 p(value) | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             log(dump(value)) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
|     commands.add_command( | ||||
|         'dump-file', | ||||
|         'Dumps value to dump.lua', | ||||
|         function(args) | ||||
|             local player = game.player | ||||
|             local p | ||||
|             if player then | ||||
|                 p = player.print | ||||
|                 if not player.admin then | ||||
|                     p('Only admins can use this command.') | ||||
|                     return | ||||
|                 if not suc then | ||||
|                     player.print(v) | ||||
|                     return false | ||||
|                 end | ||||
|             else | ||||
|                 p = player.print | ||||
|             end | ||||
|             if args.parameter == nil then | ||||
|                 return | ||||
|             end | ||||
|             local func, err = loadstring('return ' .. args.parameter) | ||||
|  | ||||
|             if not func then | ||||
|                 p(err) | ||||
|                 return | ||||
|                 log(dump(v)) | ||||
|             end | ||||
|         ) | ||||
|  | ||||
|             local suc, value = pcall(func) | ||||
|     Commands.new('dump-file', 'Dumps value to dump.lua') | ||||
|         :require_admin() | ||||
|         :add_parameter('value', false, 'string') | ||||
|         :callback( | ||||
|             function (player, value) | ||||
|                 local func, err = loadstring('return ' .. value) | ||||
|  | ||||
|             if not suc then | ||||
|                 p(value) | ||||
|                 return | ||||
|                 if not func then | ||||
|                     player.print(err) | ||||
|                     return false | ||||
|                 end | ||||
|  | ||||
|                 local suc, v = pcall(func) | ||||
|  | ||||
|                 if not suc then | ||||
|                     player.print(v) | ||||
|                     return false | ||||
|                 end | ||||
|  | ||||
|                 v = dump(v) | ||||
|                 game.write_file('dump.lua', v, false) | ||||
|             end | ||||
|  | ||||
|             value = dump(value) | ||||
|             game.write_file('dump.lua', value, false) | ||||
|         end | ||||
|     ) | ||||
|         ) | ||||
| end | ||||
|   | ||||
| @@ -42,7 +42,7 @@ function Public.show(container) | ||||
|     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 = 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 | ||||
|   | ||||
| @@ -75,7 +75,7 @@ function Public.show(container) | ||||
|         type = 'sprite-button', | ||||
|         name = refresh_name, | ||||
|         sprite = 'utility/reset', | ||||
|         tooltip = 'refresh' | ||||
|         tooltip = 'Refresh' | ||||
|     } | ||||
|     local refresh_button_style = refresh_button.style | ||||
|     refresh_button_style.width = 32 | ||||
| @@ -108,21 +108,32 @@ function Public.show(container) | ||||
|     Gui.set_data(refresh_button, data) | ||||
| end | ||||
|  | ||||
| local function draw_element_headers(element_panel, values, selected_index) | ||||
|     local copy = {} | ||||
|     for k, v in pairs(values) do | ||||
|         copy[k] = v | ||||
| local function rec(children, copy) | ||||
|     for key, child in next, children do | ||||
|         if child.name then | ||||
|             copy[key] = child | ||||
|         elseif type(child) == 'table' then | ||||
|             rec(child, copy) | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| local function deepCopy(children) | ||||
|     local copy = {} | ||||
|     rec(children, copy) | ||||
|     return copy | ||||
| end | ||||
|  | ||||
| local function draw_element_headers(element_panel, values, selected_index) | ||||
|     local copy = deepCopy(values) | ||||
|  | ||||
|     local selected_header = nil | ||||
|     local element_map = Gui.element_map() | ||||
|     local name_map = Gui.names | ||||
|  | ||||
|     for ei, stored_data in pairs(copy) do | ||||
|         local ele = element_map[ei] | ||||
|         local ele_name = '' | ||||
|         if ele and ele.valid then | ||||
|             ele_name = ele.name | ||||
|         if stored_data and stored_data.name then | ||||
|             ele_name = stored_data.name | ||||
|         end | ||||
|  | ||||
|         local gui_name = name_map[ele_name] | ||||
| @@ -161,6 +172,8 @@ Gui.on_click( | ||||
|         if not header_data then | ||||
|             return | ||||
|         end | ||||
|         Gui.clear(element) | ||||
|  | ||||
|         local values = header_data.values | ||||
|         local player_index = header_data.player_index | ||||
|  | ||||
| @@ -200,6 +213,7 @@ Gui.on_click( | ||||
|         if not header_data then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local stored_data = header_data.stored_data | ||||
|         local element_index = header_data.element_index | ||||
|  | ||||
|   | ||||
| @@ -5,16 +5,13 @@ local Public = {} | ||||
|  | ||||
| local pages = { | ||||
|     require 'utils.debug.public_global_view', | ||||
|     require 'utils.debug.global_view' | ||||
|     require 'utils.debug.global_view', | ||||
|     require 'utils.debug.gui_data_view', | ||||
|     require 'utils.debug.package_view', | ||||
|     require 'utils.debug._g_view', | ||||
|     require 'utils.debug.event_view' | ||||
| } | ||||
|  | ||||
| if _DEBUG then | ||||
|     pages[#pages + 1] = require 'utils.debug.gui_data_view' | ||||
|     pages[#pages + 1] = require 'utils.debug.package_view' | ||||
|     pages[#pages + 1] = require 'utils.debug._g_view' | ||||
|     pages[#pages + 1] = require 'utils.debug.event_view' | ||||
| end | ||||
|  | ||||
| local main_frame_name = Gui.uid_name() | ||||
| local close_name = Gui.uid_name() | ||||
| local tab_name = Gui.uid_name() | ||||
| @@ -40,8 +37,8 @@ function Public.open_debug(player) | ||||
|     frame_style.height = 600 | ||||
|     frame_style.width = 1100 | ||||
|  | ||||
|     local tab_flow = frame.add {type = 'flow', direction = 'horizontal'} | ||||
|     local container = frame.add {type = 'flow'} | ||||
|     local tab_flow = frame.add {type = 'flow', direction = 'horizontal', name = 'tab_flow'} | ||||
|     local container = frame.add {type = 'flow', name = 'container'} | ||||
|     container.style.vertically_stretchable = true | ||||
|  | ||||
|     local data = {} | ||||
| @@ -108,4 +105,6 @@ Gui.on_click( | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Public.main_frame_name = main_frame_name | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -106,6 +106,10 @@ end | ||||
| function Public.dump_function(func) | ||||
|     local res = {'upvalues:\n'} | ||||
|  | ||||
|     if debug.getupvalue == nil then | ||||
|         return concat(res) | ||||
|     end | ||||
|  | ||||
|     local i = 1 | ||||
|     while true do | ||||
|         local n, v = debug.getupvalue(func, i) | ||||
|   | ||||
| @@ -13,23 +13,44 @@ 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 filter_text_box_name = Gui.uid_name() | ||||
| local refresh_name = Gui.uid_name() | ||||
|  | ||||
| Public.name = 'Global' | ||||
|  | ||||
| function Public.show(container) | ||||
| function Public.show(container, filter) | ||||
|     container.clear() | ||||
|     local main_flow = container.add {type = 'flow', direction = 'horizontal'} | ||||
|  | ||||
|     local left_panel = main_flow.add {type = 'scroll-pane', name = left_panel_name} | ||||
|     local left_flow = main_flow.add({type = 'flow', direction = 'vertical'}) | ||||
|     left_flow.style.width = 400 | ||||
|  | ||||
|     local left_top_flow = left_flow.add {type = 'flow', direction = 'horizontal'} | ||||
|  | ||||
|     local filter_text_name = left_top_flow.add {type = 'text-box', name = filter_text_box_name, tooltip = 'Filter for tokens', text = filter or ''} | ||||
|  | ||||
|     if filter then | ||||
|         filter_text_name.focus() | ||||
|     end | ||||
|  | ||||
|     local left_panel = left_flow.add {type = 'scroll-pane', name = left_panel_name} | ||||
|     local left_panel_style = left_panel.style | ||||
|     left_panel_style.width = 400 | ||||
|  | ||||
|     for token_id, token_name in pairs(Global.names) do | ||||
|         local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = token_name} | ||||
|         Gui.set_data(header, token_id) | ||||
|         if filter then | ||||
|             if token_name:lower():find(filter:lower()) then | ||||
|                 local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = token_name} | ||||
|                 Gui.set_data(header, token_id) | ||||
|             end | ||||
|         else | ||||
|             local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = token_name} | ||||
|             Gui.set_data(header, token_id) | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     local right_flow = main_flow.add {type = 'flow', direction = 'vertical'} | ||||
|     right_flow.style.horizontally_stretchable = true | ||||
|  | ||||
|     local right_top_flow = right_flow.add {type = 'flow', direction = 'horizontal'} | ||||
|  | ||||
| @@ -39,7 +60,7 @@ function Public.show(container) | ||||
|     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 = 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 | ||||
| @@ -93,9 +114,9 @@ Gui.on_click( | ||||
|  | ||||
|         local id = Global.get_global(token_id) | ||||
|         local content = dump(id) or 'Could not load data.' | ||||
|         if content:find('function_handlers') then | ||||
|             content = '{}' -- desync handler | ||||
|         end | ||||
|         -- if content:find('function_handlers') then | ||||
|         --     content = '{}' -- desync handler | ||||
|         -- end | ||||
|         right_panel.text = content | ||||
|     end | ||||
| ) | ||||
| @@ -120,6 +141,19 @@ Gui.on_text_changed( | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Gui.on_text_changed( | ||||
|     filter_text_box_name, | ||||
|     function(event) | ||||
|         local element = event.element | ||||
|  | ||||
|         local text = element.text | ||||
|         local parent = element.parent.parent.parent.parent | ||||
|  | ||||
|         Gui.remove_data_recursively(parent) | ||||
|         Public.show(parent, text) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Gui.on_click( | ||||
|     refresh_name, | ||||
|     function(event) | ||||
|   | ||||
| @@ -111,9 +111,6 @@ local on_player_joined_game = function(event) | ||||
| end | ||||
|  | ||||
| local on_player_created = function(event) | ||||
|     if not this.modded then | ||||
|         return | ||||
|     end | ||||
|     if this.disabled then | ||||
|         return | ||||
|     end | ||||
| @@ -151,9 +148,6 @@ local on_player_created = function(event) | ||||
| end | ||||
|  | ||||
| local on_player_respawned = function(event) | ||||
|     if not this.modded then | ||||
|         return | ||||
|     end | ||||
|     if this.disabled then | ||||
|         return | ||||
|     end | ||||
| @@ -162,7 +156,7 @@ local on_player_respawned = function(event) | ||||
| end | ||||
|  | ||||
| local on_cutscene_waypoint_reached = function(event) | ||||
|     if not this.modded then | ||||
|     if this.disabled then | ||||
|         return | ||||
|     end | ||||
|     if not crash_site.is_crash_site_cutscene(event) then | ||||
| @@ -187,7 +181,7 @@ local on_cutscene_waypoint_reached = function(event) | ||||
| end | ||||
|  | ||||
| local skip_crash_site_cutscene = function(event) | ||||
|     if not this.modded then | ||||
|     if this.disabled then | ||||
|         return | ||||
|     end | ||||
|  | ||||
| @@ -216,10 +210,6 @@ local skip_crash_site_cutscene = function(event) | ||||
| end | ||||
|  | ||||
| local on_cutscene_cancelled = function(event) | ||||
|     if not this.modded then | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     if this.disabled then | ||||
|         return | ||||
|     end | ||||
| @@ -315,7 +305,6 @@ Event.on_init( | ||||
|     function() | ||||
|         local game_has_mods = is_game_modded() | ||||
|         if game_has_mods then | ||||
|             this.modded = true | ||||
|             this.created_items = created_items() | ||||
|             this.respawn_items = respawn_items() | ||||
|             this.crashed_ship_items = ship_items() | ||||
|   | ||||
							
								
								
									
										307
									
								
								utils/gui.lua
									
									
									
									
									
								
							
							
						
						
									
										307
									
								
								utils/gui.lua
									
									
									
									
									
								
							| @@ -22,10 +22,10 @@ local local_settings = { | ||||
| local main_gui_tabs = {} | ||||
| local screen_elements = {} | ||||
| local remove_data_recursively | ||||
|  | ||||
| local concat = table.concat | ||||
| local names = {} | ||||
| -- global | ||||
| local data = {} | ||||
| local element_map = {} | ||||
| local settings = { | ||||
|     mod_gui_top_frame = false, | ||||
|     disabled_tabs = {}, | ||||
| @@ -34,13 +34,14 @@ local settings = { | ||||
|  | ||||
| Public.token = | ||||
|     Global.register( | ||||
|     {data = data, element_map = element_map, settings = settings}, | ||||
|     function(tbl) | ||||
|         data = tbl.data | ||||
|         element_map = tbl.element_map | ||||
|         settings = tbl.settings | ||||
|     end | ||||
| ) | ||||
|         { data = data, settings = settings }, | ||||
|         function (tbl) | ||||
|             data = tbl.data | ||||
|             settings = tbl.settings | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| Public.names = names | ||||
|  | ||||
| Public.beam = 'file/utils/files/beam.png' | ||||
| Public.beam_1 = 'file/utils/files/beam_1.png' | ||||
| @@ -61,7 +62,20 @@ Public.info_icon = 'file/utils/files/info.png' | ||||
| Public.mod_gui_button_enabled = false | ||||
|  | ||||
| function Public.uid_name() | ||||
|     return tostring(Token.uid()) | ||||
|     if game then | ||||
|         return error('This function is not allowed to be called in this context.', 2) | ||||
|     end | ||||
|  | ||||
|     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 | ||||
|  | ||||
| function Public.uid() | ||||
| @@ -121,9 +135,10 @@ function Public.set_data(element, value) | ||||
|             data[player_index] = values | ||||
|         end | ||||
|  | ||||
|         values[element.index] = value | ||||
|         values[element.index] = { value = value, name = element.name } | ||||
|     end | ||||
| end | ||||
|  | ||||
| local set_data = Public.set_data | ||||
|  | ||||
| -- Associates data with the LuaGuiElement. If data is nil then removes the data | ||||
| @@ -151,58 +166,7 @@ function Public.set_data_parent(parent, element, value) | ||||
|             values[parent.index] = {} | ||||
|         end | ||||
|  | ||||
|         values[parent.index][element.index] = value | ||||
|     end | ||||
| end | ||||
|  | ||||
| -- Associates data with the LuaGuiElement along with the tag. If data is nil then removes the data | ||||
| function Public.set_data_custom(tag, element, value) | ||||
|     if not tag then | ||||
|         return error('A tag is required', 2) | ||||
|     end | ||||
|  | ||||
|     local player_index = element.player_index | ||||
|     local values = data[player_index] | ||||
|  | ||||
|     if value == nil then | ||||
|         if not values then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local tags = values[tag] | ||||
|         if not tags then | ||||
|             if next(values) == nil then | ||||
|                 data[player_index] = nil | ||||
|             end | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if element.remove then | ||||
|             values[tag] = nil | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         tags[element.index] = nil | ||||
|  | ||||
|         if next(tags) == nil then | ||||
|             values[tag] = nil | ||||
|         end | ||||
|     else | ||||
|         if not values then | ||||
|             values = { | ||||
|                 [tag] = {} | ||||
|             } | ||||
|             data[player_index] = values | ||||
|         end | ||||
|  | ||||
|         local tags = values[tag] | ||||
|  | ||||
|         if not tags then | ||||
|             values[tag] = {} | ||||
|             tags = values[tag] | ||||
|         end | ||||
|  | ||||
|         tags[element.index] = value | ||||
|         values[parent.index][element.index] = { value = value, name = element.name } | ||||
|     end | ||||
| end | ||||
|  | ||||
| @@ -219,7 +183,7 @@ function Public.get_data(element) | ||||
|         return nil | ||||
|     end | ||||
|  | ||||
|     return values[element.index] | ||||
|     return values[element.index].value | ||||
| end | ||||
|  | ||||
| -- Gets the Associated data with this LuaGuiElement if any. | ||||
| @@ -243,51 +207,28 @@ function Public.get_data_parent(parent, element) | ||||
|         return nil | ||||
|     end | ||||
|  | ||||
|     return values[element.index] | ||||
| end | ||||
|  | ||||
| -- Gets the Associated data with this LuaGuiElement if any. | ||||
| function Public.get_data_custom(tag, element) | ||||
|     if not tag then | ||||
|         return error('A tag is required', 2) | ||||
|     end | ||||
|     if not element then | ||||
|         return error('An element is required', 2) | ||||
|     end | ||||
|  | ||||
|     local player_index = element.player_index | ||||
|  | ||||
|     local values = data[player_index] | ||||
|     if not values then | ||||
|         return nil | ||||
|     end | ||||
|  | ||||
|     values = values[tag] | ||||
|     if not values then | ||||
|         return nil | ||||
|     end | ||||
|  | ||||
|     return values[element.index] | ||||
|     return values[element.index].value | ||||
| end | ||||
|  | ||||
| -- Adds a gui that is alike the factorio native gui. | ||||
| function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_settings_button_name, close_main_frame_name, name, info, inside_table_count) | ||||
| function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_settings_button_name, | ||||
|                                             close_main_frame_name, name, info, inside_table_count) | ||||
|     if not align then | ||||
|         return | ||||
|     end | ||||
|     local main_frame | ||||
|     if align == 'left' then | ||||
|         validate_frame_and_destroy(player.gui.left, set_frame_name) | ||||
|         main_frame = player.gui.left.add {type = 'frame', name = set_frame_name, direction = 'vertical'} | ||||
|         main_frame = player.gui.left.add { type = 'frame', name = set_frame_name, direction = 'vertical' } | ||||
|     elseif align == 'center' then | ||||
|         validate_frame_and_destroy(player.gui.center, set_frame_name) | ||||
|         main_frame = player.gui.center.add {type = 'frame', name = set_frame_name, direction = 'vertical'} | ||||
|         main_frame = player.gui.center.add { type = 'frame', name = set_frame_name, direction = 'vertical' } | ||||
|     elseif align == 'screen' then | ||||
|         validate_frame_and_destroy(player.gui.screen, set_frame_name) | ||||
|         main_frame = player.gui.screen.add {type = 'frame', name = set_frame_name, direction = 'vertical'} | ||||
|         main_frame = player.gui.screen.add { type = 'frame', name = set_frame_name, direction = 'vertical' } | ||||
|     end | ||||
|  | ||||
|     local titlebar = main_frame.add {type = 'flow', name = 'titlebar', direction = 'horizontal'} | ||||
|     local titlebar = main_frame.add { type = 'flow', name = 'titlebar', direction = 'horizontal' } --[[@as LuaGuiElement]] | ||||
|     titlebar.style.horizontal_spacing = 8 | ||||
|     titlebar.style = 'horizontal_flow' | ||||
|  | ||||
| @@ -302,7 +243,7 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s | ||||
|         caption = name, | ||||
|         ignored_by_interaction = true | ||||
|     } | ||||
|     local widget = titlebar.add {type = 'empty-widget', style = 'draggable_space', ignored_by_interaction = true} | ||||
|     local widget = titlebar.add { type = 'empty-widget', style = 'draggable_space', ignored_by_interaction = true } | ||||
|     widget.style.left_margin = 4 | ||||
|     widget.style.right_margin = 4 | ||||
|     widget.style.height = 24 | ||||
| @@ -315,7 +256,7 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s | ||||
|                 name = set_settings_button_name, | ||||
|                 style = 'frame_action_button', | ||||
|                 sprite = Public.settings_white_icon, | ||||
|                 mouse_button_filter = {'left'}, | ||||
|                 mouse_button_filter = { 'left' }, | ||||
|                 hovered_sprite = Public.settings_black_icon, | ||||
|                 clicked_sprite = Public.settings_black_icon, | ||||
|                 tooltip = 'Settings', | ||||
| @@ -329,7 +270,7 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s | ||||
|                 name = set_settings_button_name, | ||||
|                 style = 'frame_action_button', | ||||
|                 sprite = Public.info_icon, | ||||
|                 mouse_button_filter = {'left'}, | ||||
|                 mouse_button_filter = { 'left' }, | ||||
|                 hovered_sprite = Public.info_icon, | ||||
|                 clicked_sprite = Public.info_icon, | ||||
|                 tooltip = 'Info', | ||||
| @@ -345,7 +286,7 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s | ||||
|             type = 'sprite-button', | ||||
|             name = close_main_frame_name, | ||||
|             style = 'frame_action_button', | ||||
|             mouse_button_filter = {'left'}, | ||||
|             mouse_button_filter = { 'left' }, | ||||
|             sprite = 'utility/close_white', | ||||
|             hovered_sprite = 'utility/close_black', | ||||
|             clicked_sprite = 'utility/close_black', | ||||
| @@ -358,10 +299,10 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s | ||||
|  | ||||
|     local inside_frame = | ||||
|         main_frame.add { | ||||
|         type = 'table', | ||||
|         column_count = 1 or inside_table_count, | ||||
|         name = 'inside_frame' | ||||
|     } | ||||
|             type = 'table', | ||||
|             column_count = 1 or inside_table_count, | ||||
|             name = 'inside_frame' | ||||
|         } | ||||
|  | ||||
|     return main_frame, inside_frame | ||||
| end | ||||
| @@ -382,6 +323,7 @@ function Public.remove_data_recursively(element) | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| remove_data_recursively = Public.remove_data_recursively | ||||
|  | ||||
| local remove_children_data | ||||
| @@ -399,6 +341,7 @@ function Public.remove_children_data(element) | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| remove_children_data = Public.remove_children_data | ||||
|  | ||||
| function Public.destroy(element) | ||||
| @@ -475,12 +418,13 @@ local function handler_factory(event_id) | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     return function(element_name, handler) | ||||
|     return function (element_name, handler) | ||||
|         if not element_name then | ||||
|             return error('Element name is required when passing it onto the handler_factory.', 2) | ||||
|         end | ||||
|         if not handler or not type(handler) == 'function' then | ||||
|             return error('Handler is required when passing it onto the handler_factory and needs to be of type function.', 2) | ||||
|             return error( | ||||
|                 'Handler is required when passing it onto the handler_factory and needs to be of type function.', 2) | ||||
|         end | ||||
|  | ||||
|         if not handlers then | ||||
| @@ -507,7 +451,7 @@ local function custom_raise(handlers, element, player) | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     handler({element = element, player = player}) | ||||
|     handler({ element = element, player = player }) | ||||
| end | ||||
|  | ||||
| -- Disabled the handler so it does not clean then data table of invalid data. | ||||
| @@ -639,7 +583,7 @@ function Public.add_tab_to_gui(tbl) | ||||
|     local only_server_sided = tbl.only_server_sided or false | ||||
|  | ||||
|     if not main_gui_tabs[tbl.caption] then | ||||
|         main_gui_tabs[tbl.caption] = {id = tbl.id, name = tbl.name, admin = admin, only_server_sided = only_server_sided} | ||||
|         main_gui_tabs[tbl.caption] = { id = tbl.id, name = tbl.name, admin = admin, only_server_sided = only_server_sided } | ||||
|     else | ||||
|         error('Given name: ' .. tbl.caption .. ' already exists in table.') | ||||
|     end | ||||
| @@ -688,7 +632,7 @@ function Public.clear_all_screen_frames(player) | ||||
| end | ||||
|  | ||||
| function Public.clear_all_active_frames(player) | ||||
|     Event.raise(Public.events.on_gui_closed_main_frame, {player_index = player.index}) | ||||
|     Event.raise(Public.events.on_gui_closed_main_frame, { player_index = player.index }) | ||||
|     for _, child in pairs(player.gui.left.children) do | ||||
|         remove_data_recursively(child) | ||||
|         child.destroy() | ||||
| @@ -771,7 +715,8 @@ end | ||||
|  | ||||
| local function top_button(player) | ||||
|     if settings.mod_gui_top_frame then | ||||
|         local button = Public.add_mod_button(player, {type = 'sprite-button', name = main_button_name, sprite = 'item/raw-fish', style = Public.button_style}) | ||||
|         local button = Public.add_mod_button(player, | ||||
|             { type = 'sprite-button', name = main_button_name, sprite = 'item/raw-fish', style = Public.button_style }) | ||||
|         if button then | ||||
|             button.style.minimal_height = 36 | ||||
|             button.style.maximal_height = 36 | ||||
| @@ -782,7 +727,12 @@ local function top_button(player) | ||||
|         if player.gui.top[main_button_name] then | ||||
|             return | ||||
|         end | ||||
|         local button = player.gui.top.add({type = 'sprite-button', name = main_button_name, sprite = 'item/raw-fish', style = Public.button_style}) | ||||
|         local button = player.gui.top.add({ | ||||
|             type = 'sprite-button', | ||||
|             name = main_button_name, | ||||
|             sprite = 'item/raw-fish', | ||||
|             style = Public.button_style | ||||
|         }) | ||||
|         button.style.minimal_height = 38 | ||||
|         button.style.maximal_height = 38 | ||||
|         button.style.minimal_width = 40 | ||||
| @@ -798,17 +748,17 @@ local function top_toggle_button(player) | ||||
|     if Public.get_mod_gui_top_frame() then | ||||
|         local b = | ||||
|             Public.add_mod_button( | ||||
|             player, | ||||
|             { | ||||
|                 type = 'sprite-button', | ||||
|                 name = main_toggle_button_name, | ||||
|                 sprite = 'utility/preset', | ||||
|                 tooltip = 'Click to hide top buttons!', | ||||
|                 style = Public.button_style | ||||
|             } | ||||
|         ) | ||||
|                 player, | ||||
|                 { | ||||
|                     type = 'sprite-button', | ||||
|                     name = main_toggle_button_name, | ||||
|                     sprite = 'utility/preset', | ||||
|                     tooltip = 'Click to hide top buttons!', | ||||
|                     style = Public.button_style | ||||
|                 } | ||||
|             ) | ||||
|         if b then | ||||
|             b.style.font_color = {165, 165, 165} | ||||
|             b.style.font_color = { 165, 165, 165 } | ||||
|             b.style.font = 'heading-3' | ||||
|             b.style.minimal_height = 36 | ||||
|             b.style.maximal_height = 36 | ||||
| @@ -819,14 +769,14 @@ local function top_toggle_button(player) | ||||
|     else | ||||
|         local b = | ||||
|             player.gui.top.add( | ||||
|             { | ||||
|                 type = 'sprite-button', | ||||
|                 name = main_toggle_button_name, | ||||
|                 sprite = 'utility/preset', | ||||
|                 style = Public.button_style, | ||||
|                 tooltip = 'Click to hide top buttons!' | ||||
|             } | ||||
|         ) | ||||
|                 { | ||||
|                     type = 'sprite-button', | ||||
|                     name = main_toggle_button_name, | ||||
|                     sprite = 'utility/preset', | ||||
|                     style = Public.button_style, | ||||
|                     tooltip = 'Click to hide top buttons!' | ||||
|                 } | ||||
|             ) | ||||
|         b.style.padding = 2 | ||||
|         b.style.width = 20 | ||||
|         b.style.maximal_height = 38 | ||||
| @@ -845,32 +795,33 @@ local function draw_main_frame(player) | ||||
|  | ||||
|     local admins = Server.get_admins_data() | ||||
|  | ||||
|     local frame, inside_frame = Public.add_main_frame_with_toolbar(player, 'left', main_frame_name, nil, close_button_name, 'Comfy Factorio') | ||||
|     local tabbed_pane = inside_frame.add({type = 'tabbed-pane', name = 'tabbed_pane'}) | ||||
|     local frame, inside_frame = Public.add_main_frame_with_toolbar(player, 'left', main_frame_name, nil, | ||||
|         close_button_name, 'Comfy Factorio') | ||||
|     local tabbed_pane = inside_frame.add({ type = 'tabbed-pane', name = 'tabbed_pane' }) | ||||
|     for name, callback in pairs(tabs) do | ||||
|         if not settings.disabled_tabs[name] then | ||||
|             local secs = Server.get_current_time() | ||||
|             if callback.only_server_sided then | ||||
|                 if secs then | ||||
|                     local tab = tabbed_pane.add({type = 'tab', caption = name, name = callback.name}) | ||||
|                     local name_frame = tabbed_pane.add({type = 'frame', name = name, direction = 'vertical'}) | ||||
|                     local tab = tabbed_pane.add({ type = 'tab', caption = name, name = callback.name }) | ||||
|                     local name_frame = tabbed_pane.add({ type = 'frame', name = name, direction = 'vertical' }) | ||||
|                     tabbed_pane.add_tab(tab, name_frame) | ||||
|                 end | ||||
|             elseif callback.admin == true then | ||||
|                 if player.admin then | ||||
|                     if not secs then | ||||
|                         local tab = tabbed_pane.add({type = 'tab', caption = name, name = callback.name}) | ||||
|                         local name_frame = tabbed_pane.add({type = 'frame', name = name, direction = 'vertical'}) | ||||
|                         local tab = tabbed_pane.add({ type = 'tab', caption = name, name = callback.name }) | ||||
|                         local name_frame = tabbed_pane.add({ type = 'frame', name = name, direction = 'vertical' }) | ||||
|                         tabbed_pane.add_tab(tab, name_frame) | ||||
|                     elseif secs and admins[player.name] then | ||||
|                         local tab = tabbed_pane.add({type = 'tab', caption = name, name = callback.name}) | ||||
|                         local name_frame = tabbed_pane.add({type = 'frame', name = name, direction = 'vertical'}) | ||||
|                         local tab = tabbed_pane.add({ type = 'tab', caption = name, name = callback.name }) | ||||
|                         local name_frame = tabbed_pane.add({ type = 'frame', name = name, direction = 'vertical' }) | ||||
|                         tabbed_pane.add_tab(tab, name_frame) | ||||
|                     end | ||||
|                 end | ||||
|             else | ||||
|                 local tab = tabbed_pane.add({type = 'tab', caption = name, name = callback.name}) | ||||
|                 local name_frame = tabbed_pane.add({type = 'frame', name = name, direction = 'vertical'}) | ||||
|                 local tab = tabbed_pane.add({ type = 'tab', caption = name, name = callback.name }) | ||||
|                 local name_frame = tabbed_pane.add({ type = 'frame', name = name, direction = 'vertical' }) | ||||
|                 tabbed_pane.add_tab(tab, name_frame) | ||||
|             end | ||||
|         end | ||||
| @@ -907,7 +858,7 @@ function Public.refresh(player) | ||||
|     for _, tab in pairs(tabbed_pane.tabs) do | ||||
|         if tab.content.name ~= frame.name then | ||||
|             tab.content.clear() | ||||
|             Event.raise(Public.events.on_gui_removal, {player_index = player.index}) | ||||
|             Event.raise(Public.events.on_gui_removal, { player_index = player.index }) | ||||
|         end | ||||
|     end | ||||
|  | ||||
| @@ -980,7 +931,7 @@ Public.on_value_changed = handler_factory(defines.events.on_gui_value_changed) | ||||
|  | ||||
| Public.on_click( | ||||
|     main_button_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Main button') | ||||
|         if is_spamming then | ||||
|             return | ||||
| @@ -991,9 +942,10 @@ Public.on_click( | ||||
|         if frame then | ||||
|             remove_data_recursively(frame) | ||||
|             frame.destroy() | ||||
|             Event.raise(Public.events.on_gui_removal, {player_index = player.index}) | ||||
|             Event.raise(Public.events.on_gui_removal, { player_index = player.index }) | ||||
|             local active_frame = Public.get_player_active_frame(player) | ||||
|             Event.raise(Public.events.on_gui_closed_main_frame, {player_index = player.index, element = active_frame or nil}) | ||||
|             Event.raise(Public.events.on_gui_closed_main_frame, | ||||
|                 { player_index = player.index, element = active_frame or nil }) | ||||
|         else | ||||
|             draw_main_frame(player) | ||||
|         end | ||||
| @@ -1002,11 +954,11 @@ Public.on_click( | ||||
|  | ||||
| Public.on_click( | ||||
|     close_button_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = event.player | ||||
|         local frame = Public.get_parent_frame(player) | ||||
|         local active_frame = Public.get_player_active_frame(player) | ||||
|         Event.raise(Public.events.on_gui_closed_main_frame, {player_index = player.index, element = active_frame or nil}) | ||||
|         Event.raise(Public.events.on_gui_closed_main_frame, { player_index = player.index, element = active_frame or nil }) | ||||
|         if frame then | ||||
|             remove_data_recursively(frame) | ||||
|             frame.destroy() | ||||
| @@ -1016,10 +968,10 @@ Public.on_click( | ||||
|  | ||||
| Public.on_custom_close( | ||||
|     main_frame_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = event.player | ||||
|         local active_frame = Public.get_player_active_frame(player) | ||||
|         Event.raise(Public.events.on_gui_closed_main_frame, {player_index = player.index, element = active_frame or nil}) | ||||
|         Event.raise(Public.events.on_gui_closed_main_frame, { player_index = player.index, element = active_frame or nil }) | ||||
|         local frame = Public.get_parent_frame(player) | ||||
|         if frame then | ||||
|             remove_data_recursively(frame) | ||||
| @@ -1030,7 +982,7 @@ Public.on_custom_close( | ||||
|  | ||||
| Public.on_click( | ||||
|     main_toggle_button_name, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local button = event.element | ||||
|         local player = event.player | ||||
|         local top = player.gui.top | ||||
| @@ -1082,7 +1034,7 @@ Public.on_click( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_gui_click, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local element = event.element | ||||
|         if not element or not element.valid then | ||||
|             return | ||||
| @@ -1116,7 +1068,7 @@ Event.add( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_created, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if local_settings.toggle_button then | ||||
|             top_toggle_button(player) | ||||
| @@ -1127,67 +1079,14 @@ Event.add( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         top_button(player) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| if _DEBUG then | ||||
|     local concat = table.concat | ||||
|  | ||||
|     local names = {} | ||||
|     Public.names = names | ||||
|  | ||||
|     function Public.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 | ||||
|  | ||||
|     function Public.set_data(element, value) | ||||
|         local player_index = element.player_index | ||||
|         local values = data[player_index] | ||||
|  | ||||
|         if value == nil then | ||||
|             if not values then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|             local index = element.index | ||||
|             values[index] = nil | ||||
|             element_map[index] = nil | ||||
|  | ||||
|             if next(values) == nil then | ||||
|                 data[player_index] = nil | ||||
|             end | ||||
|         else | ||||
|             if not values then | ||||
|                 values = {} | ||||
|                 data[player_index] = values | ||||
|             end | ||||
|  | ||||
|             local index = element.index | ||||
|             values[index] = value | ||||
|             element_map[index] = element | ||||
|         end | ||||
|     end | ||||
|     set_data = Public.set_data | ||||
|  | ||||
|     function Public.data() | ||||
|         return data | ||||
|     end | ||||
|  | ||||
|     function Public.element_map() | ||||
|         return element_map | ||||
|     end | ||||
| function Public.data() | ||||
|     return data | ||||
| end | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -251,7 +251,7 @@ Gui.on_click( | ||||
|         local element = event.element | ||||
|  | ||||
|         local button = event.button | ||||
|         local data = Gui.get_data_custom(tag, element) | ||||
|         local data = Gui.get_data(element) | ||||
|         if not data then | ||||
|             return | ||||
|         end | ||||
| @@ -288,7 +288,7 @@ Gui.on_click( | ||||
|         local player = event.player | ||||
|         local element = event.element | ||||
|  | ||||
|         local data = Gui.get_data_custom(tag, element) | ||||
|         local data = Gui.get_data(element) | ||||
|         if not data then | ||||
|             return | ||||
|         end | ||||
| @@ -360,7 +360,6 @@ Gui.on_click( | ||||
|     module_name, | ||||
|     function(event) | ||||
|         local player = event.player | ||||
|         Gui.set_data_custom(tag, {player_index = player.index, remove = true}, nil) | ||||
|         Gui.reload_active_tab(player) | ||||
|     end | ||||
| ) | ||||
| @@ -403,11 +402,5 @@ Gui.on_click( | ||||
|  | ||||
| Event.add(defines.events.on_player_joined_game, on_player_joined_game) | ||||
| Event.add(defines.events.on_player_left_game, on_player_left_game) | ||||
| Event.add( | ||||
|     Gui.events.on_gui_removal, | ||||
|     function(event) | ||||
|         Gui.set_data_custom(tag, {player_index = event.player_index, remove = true}, nil) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| return Public | ||||
|   | ||||
| @@ -437,7 +437,7 @@ Public.gui_data = function(data) | ||||
|                 tooltip = tooltip | ||||
|             } | ||||
|  | ||||
|             Gui.set_data_custom('Players', name_label, player.index) | ||||
|             Gui.set_data(name_label, player.index) | ||||
|  | ||||
|             name_label.style.font = 'default' | ||||
|             name_label.style.font_color = { | ||||
| @@ -591,7 +591,7 @@ Public.gui_data = function(data) | ||||
|             poke_flow.style.right_padding = 20 | ||||
|             local poke_label = poke_flow.add {type = 'label', name = 'button_spacer_' .. index, caption = ''} | ||||
|             local poke_button = poke_flow.add {type = 'button', name = poke_player_frame_name, caption = player.pokes} | ||||
|             Gui.set_data_custom('Players', poke_button, player.index) | ||||
|             Gui.set_data(poke_button, player.index) | ||||
|             poke_button.style.font = 'default' | ||||
|             poke_button.tooltip = 'Poke ' .. player.name .. ' with a random message!\nDoes not work poking yourself :<' | ||||
|             poke_label.style.font_color = {r = 0.83, g = 0.83, b = 0.83} | ||||
|   | ||||
| @@ -1,136 +0,0 @@ | ||||
| local Server = require 'utils.server' | ||||
| local Global = require 'utils.globals' | ||||
|  | ||||
| local mapkeeper = '[color=blue]Mapkeeper:[/color]' | ||||
|  | ||||
| local Public = {} | ||||
|  | ||||
| local this = { | ||||
|     scenarioname = '', | ||||
|     reset_are_you_sure = false, | ||||
|     restart = false, | ||||
|     soft_reset = false, | ||||
|     shutdown = false, | ||||
|     accepted_params = { | ||||
|         ['restart'] = true, | ||||
|         ['resetnow'] = true, | ||||
|         ['shutdown'] = true, | ||||
|         ['restartnow'] = true | ||||
|     } | ||||
| } | ||||
|  | ||||
| Global.register( | ||||
|     this, | ||||
|     function(t) | ||||
|         this = t | ||||
|     end | ||||
| ) | ||||
|  | ||||
| commands.add_command( | ||||
|     'scenario', | ||||
|     'Usable only for admins - controls the scenario!', | ||||
|     function(cmd) | ||||
|         local p | ||||
|         local player = game.player | ||||
|  | ||||
|         if not player or not player.valid then | ||||
|             p = log | ||||
|         else | ||||
|             p = player.print | ||||
|             if not player.admin then | ||||
|                 return | ||||
|             end | ||||
|         end | ||||
|  | ||||
|         local param = cmd.parameter | ||||
|  | ||||
|         if this.accepted_params[param] then | ||||
|             goto continue | ||||
|         else | ||||
|             p('[ERROR] Arguments was invalid.') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         ::continue:: | ||||
|  | ||||
|         if not this.reset_are_you_sure then | ||||
|             this.reset_are_you_sure = true | ||||
|             p('[WARNING] This command will disable the soft-reset feature, run this command again if you really want to do this!') | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         if param == 'restart' then | ||||
|             if this.restart then | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 this.restart = false | ||||
|                 this.soft_reset = true | ||||
|                 p('[SUCCESS] Soft-reset is once again enabled.') | ||||
|                 return | ||||
|             else | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 this.restart = true | ||||
|                 this.soft_reset = false | ||||
|                 if this.shutdown then | ||||
|                     this.shutdown = false | ||||
|                 end | ||||
|                 p('[WARNING] Soft-reset is disabled! Server will restart from scenario to load new changes.') | ||||
|                 return | ||||
|             end | ||||
|         elseif param == 'restartnow' then | ||||
|             this.reset_are_you_sure = nil | ||||
|             p(player.name .. ' restarted the game.') | ||||
|             Server.start_scenario(this.scenarioname) | ||||
|             return | ||||
|         elseif param == 'shutdown' then | ||||
|             if this.shutdown then | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 this.shutdown = false | ||||
|                 this.soft_reset = true | ||||
|                 p('[SUCCESS] Soft-reset is once again enabled.') | ||||
|                 return | ||||
|             else | ||||
|                 this.reset_are_you_sure = nil | ||||
|                 this.shutdown = true | ||||
|                 this.soft_reset = false | ||||
|                 if this.restart then | ||||
|                     this.restart = false | ||||
|                 end | ||||
|                 p('[WARNING] Soft-reset is disabled! Server will shutdown. Most likely because of updates.') | ||||
|                 return | ||||
|             end | ||||
|         elseif param == 'reset' then | ||||
|             this.reset_are_you_sure = nil | ||||
|             if player and player.valid then | ||||
|                 game.print(mapkeeper .. ' ' .. player.name .. ', has reset the game!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|             else | ||||
|                 game.print(mapkeeper .. ' server, has reset the game!', {r = 0.98, g = 0.66, b = 0.22}) | ||||
|             end | ||||
|             -- reset_map() | ||||
|             p('[WARNING] Game has been reset!') | ||||
|             return | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|  | ||||
| function Public.map_reset_callback(data, callback) | ||||
|     if not data then | ||||
|         return | ||||
|     end | ||||
|     if not callback then | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     if not string.find(callback, '%s') and not string.find(callback, 'return') then | ||||
|         callback = 'return ' .. callback | ||||
|     end | ||||
|  | ||||
|     if type(callback) == 'function' then | ||||
|         local success, err = pcall(callback, data) | ||||
|         return success, err | ||||
|     else | ||||
|         local success, err = pcall(loadstring(callback), data) | ||||
|         return success, err | ||||
|     end | ||||
| end | ||||
|  | ||||
| return Public | ||||
							
								
								
									
										138
									
								
								utils/server.lua
									
									
									
									
									
								
							
							
						
						
									
										138
									
								
								utils/server.lua
									
									
									
									
									
								
							| @@ -22,13 +22,13 @@ local hours_to_ticks = 60 * 60 * 60 | ||||
| local ticks_to_minutes = 1 / minutes_to_ticks | ||||
| local ticks_to_hours = 1 / hours_to_ticks | ||||
|  | ||||
| local serialize_options = {sparse = true, compact = true} | ||||
| local serialize_options = { sparse = true, compact = true } | ||||
|  | ||||
| local Public = {} | ||||
|  | ||||
| local server_time = {secs = nil, tick = 0} | ||||
| local server_ups = {ups = 60} | ||||
| local start_data = {server_id = nil, server_name = nil, start_time = nil} | ||||
| local server_time = { secs = nil, tick = 0 } | ||||
| local server_ups = { ups = 60 } | ||||
| local start_data = { server_id = nil, server_name = nil, start_time = nil } | ||||
| local instances = { | ||||
|     data = {} | ||||
| } | ||||
| @@ -47,7 +47,7 @@ Global.register( | ||||
|         instances = instances, | ||||
|         admins = admins | ||||
|     }, | ||||
|     function(tbl) | ||||
|     function (tbl) | ||||
|         server_time = tbl.server_time | ||||
|         server_ups = tbl.server_ups | ||||
|         start_data = tbl.start_data | ||||
| @@ -109,6 +109,8 @@ local function output_data(primary, secondary) | ||||
|         return false | ||||
|     end | ||||
|  | ||||
|     secondary = type(secondary) == 'table' and '' or secondary | ||||
|  | ||||
|     if start_data and start_data.output then | ||||
|         local write = game.write_file | ||||
|         write(start_data.output, primary .. (secondary or '') .. newline, true, 0) | ||||
| @@ -168,7 +170,7 @@ end | ||||
| -- function() | ||||
| --      Trigger some sort of automated restart whenever the game ends. | ||||
| -- end) | ||||
| Public.events = {on_server_started = Event.generate_event_name('on_server_started'), on_changes_detected = Event.generate_event_name('on_changes_detected')} | ||||
| Public.events = { on_server_started = Event.generate_event_name('on_server_started'), on_changes_detected = Event.generate_event_name('on_changes_detected') } | ||||
|  | ||||
| --- Sends a message to the linked discord channel. The message is sanitized of markdown server side. | ||||
| -- @param  message<string> message to send. | ||||
| @@ -210,28 +212,28 @@ end | ||||
| -- @param  message<string> message to send. | ||||
| function Public.to_discord_named(channel_name, message) | ||||
|     assert_non_empty_string_and_no_spaces(channel_name, 'channel_name') | ||||
|     output_data(concat({discord_named_tag, channel_name, ' ', message})) | ||||
|     output_data(concat({ discord_named_tag, channel_name, ' ', message })) | ||||
| end | ||||
|  | ||||
| --- Sends a message to the named discord channel. The message is not sanitized of markdown. | ||||
| -- @param  message<string> message to send. | ||||
| function Public.to_discord_named_raw(channel_name, message) | ||||
|     assert_non_empty_string_and_no_spaces(channel_name, 'channel_name') | ||||
|     output_data(concat({discord_named_raw_tag, channel_name, ' ', message})) | ||||
|     output_data(concat({ discord_named_raw_tag, channel_name, ' ', message })) | ||||
| end | ||||
|  | ||||
| --- Sends a message to the named discord channel. The message is sanitized of markdown server side, then made bold. | ||||
| -- @param  message<string> message to send. | ||||
| function Public.to_discord_named_bold(channel_name, message) | ||||
|     assert_non_empty_string_and_no_spaces(channel_name, 'channel_name') | ||||
|     output_data(concat({discord_named_bold_tag, channel_name, ' ', message})) | ||||
|     output_data(concat({ discord_named_bold_tag, channel_name, ' ', message })) | ||||
| end | ||||
|  | ||||
| --- Sends an embed message to the named discord channel. The message is sanitized of markdown server side. | ||||
| -- @param  message<string> the content of the embed. | ||||
| function Public.to_discord_named_embed(channel_name, message) | ||||
|     assert_non_empty_string_and_no_spaces(channel_name, 'channel_name') | ||||
|     output_data(concat({discord_named_embed_tag, channel_name, ' ', message})) | ||||
|     output_data(concat({ discord_named_embed_tag, channel_name, ' ', message })) | ||||
| end | ||||
|  | ||||
| --- Sends an embed message that is parsed to the named discord channel. The message is sanitized of markdown server side. | ||||
| @@ -260,7 +262,7 @@ end | ||||
| -- @param  message<string> the content of the embed. | ||||
| function Public.to_discord_named_embed_raw(channel_name, message) | ||||
|     assert_non_empty_string_and_no_spaces(channel_name, 'channel_name') | ||||
|     output_data(concat({discord_named_embed_raw_tag, channel_name, ' ', message})) | ||||
|     output_data(concat({ discord_named_embed_raw_tag, channel_name, ' ', message })) | ||||
| end | ||||
|  | ||||
| --- Sends a message to the linked admin discord channel. The message is sanitized of markdown server side. | ||||
| @@ -284,6 +286,7 @@ function Public.to_banned(message, locale) | ||||
|         output_data(discord_banned_tag .. message) | ||||
|     end | ||||
| end | ||||
|  | ||||
| --- Sends a message to the linked banned discord channel. The message is sanitized of markdown server side. | ||||
| -- @param  message<string> message to send. | ||||
| -- @param  locale<boolean> if the message should be handled as localized. | ||||
| @@ -305,6 +308,7 @@ function Public.to_jailed(message, locale) | ||||
|         output_data(discord_jailed_tag .. message) | ||||
|     end | ||||
| end | ||||
|  | ||||
| --- Sends a message to the linked connected discord channel. The message is sanitized of markdown server side. | ||||
| -- @param  message<string> message to send. | ||||
| -- @param  locale<boolean> if the message should be handled as localized. | ||||
| @@ -553,20 +557,20 @@ end | ||||
|  | ||||
| local default_ping_token = | ||||
|     Token.register( | ||||
|     function(sent_tick) | ||||
|         local now = game.tick | ||||
|         local diff = now - sent_tick | ||||
|         function (sent_tick) | ||||
|             local now = game.tick | ||||
|             local diff = now - sent_tick | ||||
|  | ||||
|         local message = concat({'Pong in ', diff, ' tick(s) ', 'sent tick: ', sent_tick, ' received tick: ', now}) | ||||
|         game.print(message) | ||||
|     end | ||||
| ) | ||||
|             local message = concat({ 'Pong in ', diff, ' tick(s) ', 'sent tick: ', sent_tick, ' received tick: ', now }) | ||||
|             game.print(message) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| --- Pings the web server. | ||||
| -- @param  func_token<token> The function that is called when the web server replies. | ||||
| -- The function is passed the tick that the ping was sent. | ||||
| function Public.ping(func_token) | ||||
|     local message = concat({ping_tag, func_token or default_ping_token, ' ', game.tick}) | ||||
|     local message = concat({ ping_tag, func_token or default_ping_token, ' ', game.tick }) | ||||
|     output_data(message) | ||||
| end | ||||
|  | ||||
| @@ -628,15 +632,15 @@ function Public.set_data(data_set, key, value) | ||||
|     local message | ||||
|     local vt = type(value) | ||||
|     if vt == 'nil' then | ||||
|         message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '"}'}) | ||||
|         message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, '"}' }) | ||||
|     elseif vt == 'string' then | ||||
|         value = double_escape(value) | ||||
|  | ||||
|         message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"\\"', value, '\\""}'}) | ||||
|         message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"\\"', value, '\\""}' }) | ||||
|     elseif vt == 'number' then | ||||
|         message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', value, '"}'}) | ||||
|         message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', value, '"}' }) | ||||
|     elseif vt == 'boolean' then | ||||
|         message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', tostring(value), '"}'}) | ||||
|         message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', tostring(value), '"}' }) | ||||
|     elseif vt == 'function' then | ||||
|         error('value cannot be a function', 2) | ||||
|     else -- table | ||||
| @@ -646,7 +650,7 @@ function Public.set_data(data_set, key, value) | ||||
|         -- Need to escape single quotes as serpent uses double quotes for strings. | ||||
|         value = value:gsub('\\', '\\\\'):gsub("'", "\\'") | ||||
|  | ||||
|         message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, "\",value:'", value, "'}"}) | ||||
|         message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, "\",value:'", value, "'}" }) | ||||
|     end | ||||
|  | ||||
|     output_data(message) | ||||
| @@ -678,14 +682,14 @@ local function send_try_get_data(data_set, key, callback_token) | ||||
|     data_set = double_escape(data_set) | ||||
|     key = double_escape(key) | ||||
|  | ||||
|     local message = concat {data_get_tag, callback_token, ' {', 'data_set:"', data_set, '",key:"', key, '"}'} | ||||
|     local message = concat { data_get_tag, callback_token, ' {', 'data_set:"', data_set, '",key:"', key, '"}' } | ||||
|     output_data(message) | ||||
| end | ||||
|  | ||||
| local function send_try_get_ban(username, callback_token) | ||||
|     username = double_escape(username) | ||||
|  | ||||
|     local message = concat {ban_get_tag, callback_token, ' {', 'username:"', username, '"}'} | ||||
|     local message = concat { ban_get_tag, callback_token, ' {', 'username:"', username, '"}' } | ||||
|     output_data(message) | ||||
| end | ||||
|  | ||||
| @@ -694,7 +698,7 @@ local function send_try_get_data_and_print(data_set, key, to_print, callback_tok | ||||
|     key = double_escape(key) | ||||
|     to_print = double_escape(to_print) | ||||
|  | ||||
|     local message = concat {data_get_and_print_tag, callback_token, ' {', 'data_set:"', data_set, '",key:"', key, '",to_print:"', to_print, '"}'} | ||||
|     local message = concat { data_get_and_print_tag, callback_token, ' {', 'data_set:"', data_set, '",key:"', key, '",to_print:"', to_print, '"}' } | ||||
|     output_data(message) | ||||
| end | ||||
|  | ||||
| @@ -702,33 +706,33 @@ local function log_antigrief_data(category, action) | ||||
|     category = double_escape(category) | ||||
|     action = double_escape(action) | ||||
|  | ||||
|     local message = concat {antigrief_tag, '{', 'category:"', category, '",action:"', action, '"}'} | ||||
|     local message = concat { antigrief_tag, '{', 'category:"', category, '",action:"', action, '"}' } | ||||
|     output_data(message) | ||||
| end | ||||
|  | ||||
| local cancelable_callback_token = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         local data_set = data.data_set | ||||
|         local keys = requests[data_set] | ||||
|         if not keys then | ||||
|             return | ||||
|         end | ||||
|         function (data) | ||||
|             local data_set = data.data_set | ||||
|             local keys = requests[data_set] | ||||
|             if not keys then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         local key = data.key | ||||
|         local callbacks = keys[key] | ||||
|         if not callbacks then | ||||
|             return | ||||
|         end | ||||
|             local key = data.key | ||||
|             local callbacks = keys[key] | ||||
|             if not callbacks then | ||||
|                 return | ||||
|             end | ||||
|  | ||||
|         keys[key] = nil | ||||
|             keys[key] = nil | ||||
|  | ||||
|         for c, _ in next, callbacks do | ||||
|             local func = Token.get(c) | ||||
|             func(data) | ||||
|             for c, _ in next, callbacks do | ||||
|                 local func = Token.get(c) | ||||
|                 func(data) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| ) | ||||
|     ) | ||||
|  | ||||
| --- Gets data from the web server's persistent data storage. | ||||
| -- The callback is passed a table {data_set: string, key: string, value: any}. | ||||
| @@ -827,7 +831,7 @@ local function cancel_try_get_data(data_set, key, callback_token) | ||||
|         callbacks[callback_token] = nil | ||||
|  | ||||
|         local func = Token.get(callback_token) | ||||
|         local data = {data_set = data_set, key = key, cancelled = true} | ||||
|         local data = { data_set = data_set, key = key, cancelled = true } | ||||
|         func(data) | ||||
|  | ||||
|         return true | ||||
| @@ -851,10 +855,10 @@ end | ||||
|  | ||||
| local timeout_token = | ||||
|     Token.register( | ||||
|     function(data) | ||||
|         cancel_try_get_data(data.data_set, data.key, data.callback_token) | ||||
|     end | ||||
| ) | ||||
|         function (data) | ||||
|             cancel_try_get_data(data.data_set, data.key, data.callback_token) | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| --- Same as Server.try_get_data but the request is cancelled if the timeout expires before the request is complete. | ||||
| -- If the request is cancelled before it is complete the callback will be called with data.cancelled = true. | ||||
| @@ -892,7 +896,7 @@ function Public.try_get_data_timeout(data_set, key, callback_token, timeout_tick | ||||
|  | ||||
|     try_get_data_cancelable(data_set, key, callback_token) | ||||
|  | ||||
|     Task.set_timeout_in_ticks(timeout_ticks, timeout_token, {data_set = data_set, key = key, callback_token = callback_token}) | ||||
|     Task.set_timeout_in_ticks(timeout_ticks, timeout_token, { data_set = data_set, key = key, callback_token = callback_token }) | ||||
| end | ||||
|  | ||||
| --- Gets all the data for the data_set from the web server's persistent data storage. | ||||
| @@ -925,7 +929,7 @@ function Public.try_get_all_data(data_set, callback_token) | ||||
|  | ||||
|     data_set = double_escape(data_set) | ||||
|  | ||||
|     local message = concat {data_get_all_tag, callback_token, ' {', 'data_set:"', data_set, '"}'} | ||||
|     local message = concat { data_get_all_tag, callback_token, ' {', 'data_set:"', data_set, '"}' } | ||||
|     output_data(message) | ||||
| end | ||||
|  | ||||
| @@ -1022,7 +1026,7 @@ function Public.on_data_set_changed(data_set, handler) | ||||
|  | ||||
|     local handlers = data_set_handlers[data_set] | ||||
|     if handlers == nil then | ||||
|         handlers = {handler} | ||||
|         handlers = { handler } | ||||
|         data_set_handlers[data_set] = handlers | ||||
|     else | ||||
|         handlers[#handlers + 1] = handler | ||||
| @@ -1051,7 +1055,7 @@ function Public.on_scenario_changed(scenario, handler) | ||||
|  | ||||
|     local handlers = scenario_handlers[scenario] | ||||
|     if handlers == nil then | ||||
|         handlers = {handler} | ||||
|         handlers = { handler } | ||||
|         scenario_handlers[scenario] = handlers | ||||
|     else | ||||
|         handlers[#handlers + 1] = handler | ||||
| @@ -1072,7 +1076,7 @@ Public.log_antigrief_data = log_antigrief_data | ||||
|  | ||||
| --- Called by the web server to determine which data_sets are being tracked. | ||||
| function Public.get_tracked_data_sets() | ||||
|     local message = {data_tracked_tag, '['} | ||||
|     local message = { data_tracked_tag, '[' } | ||||
|  | ||||
|     for k, _ in pairs(data_set_handlers) do | ||||
|         k = double_escape(k) | ||||
| @@ -1096,7 +1100,7 @@ end | ||||
|  | ||||
| --- Called by the web server to determine which scenarios is being tracked. | ||||
| function Public.get_tracked_scenario() | ||||
|     local message = {scenario_tag, ''} | ||||
|     local message = { scenario_tag, '' } | ||||
|  | ||||
|     for k, _ in pairs(scenario_handlers) do | ||||
|         k = double_escape(k) | ||||
| @@ -1245,7 +1249,7 @@ function Public.ban_sync(username, reason, admin) | ||||
|     reason = escape(reason) | ||||
|     admin = escape(admin) | ||||
|  | ||||
|     local message = concat({ban_sync_tag, '{username:"', username, '",reason:"', reason, '",admin:"', admin, '"}'}) | ||||
|     local message = concat({ ban_sync_tag, '{username:"', username, '",reason:"', reason, '",admin:"', admin, '"}' }) | ||||
|     output_data(message) | ||||
| end | ||||
|  | ||||
| @@ -1283,7 +1287,7 @@ function Public.unban_sync(username, admin) | ||||
|     username = escape(username) | ||||
|     admin = escape(admin) | ||||
|  | ||||
|     local message = concat({unbanned_sync_tag, '{username:"', username, '",admin:"', admin, '"}'}) | ||||
|     local message = concat({ unbanned_sync_tag, '{username:"', username, '",admin:"', admin, '"}' }) | ||||
|     output_data(message) | ||||
| end | ||||
|  | ||||
| @@ -1401,7 +1405,7 @@ function Public.get_current_date(pretty, as_table, current_time) | ||||
|     end | ||||
|  | ||||
|     if as_table then | ||||
|         return {year = date.year, month = date.month, day = date.day} | ||||
|         return { year = date.year, month = date.month, day = date.day } | ||||
|     elseif pretty then | ||||
|         return date.year .. '-' .. date.month .. '-' .. date.day | ||||
|     else | ||||
| @@ -1452,7 +1456,7 @@ end | ||||
|  | ||||
| --- Called by the web server to re sync which players are online. | ||||
| function Public.query_online_players() | ||||
|     local message = {query_players_tag, '['} | ||||
|     local message = { query_players_tag, '[' } | ||||
|  | ||||
|     for _, p in ipairs(game.connected_players) do | ||||
|         message[#message + 1] = '"' | ||||
| @@ -1504,6 +1508,7 @@ local function command_handler(callback, ...) | ||||
|         local success, err = pcall(callback, ...) | ||||
|         return success, err | ||||
|     else | ||||
|         ---@diagnostic disable-next-line: deprecated, param-type-mismatch | ||||
|         local success, err = pcall(loadstring(callback), ...) | ||||
|         return success, err | ||||
|     end | ||||
| @@ -1513,8 +1518,8 @@ end | ||||
| -- Doing this, enables achievements and the web-panel can communicate without any interruptions. | ||||
| commands.add_command( | ||||
|     'cc', | ||||
|     'Evaluate command', | ||||
|     function(cmd) | ||||
|     '<callback> - Evaluate command', | ||||
|     function (cmd) | ||||
|         local player = game.player | ||||
|         if player then | ||||
|             return | ||||
| @@ -1544,7 +1549,7 @@ commands.add_command( | ||||
| --  players joining or leaving. So we send our own [PLAYER-JOIN] and [PLAYER-LEAVE] tags. | ||||
| Event.add( | ||||
|     defines.events.on_player_joined_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
| @@ -1575,7 +1580,7 @@ local leave_reason_map = { | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_left_game, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player then | ||||
|             return | ||||
| @@ -1593,7 +1598,7 @@ Event.add( | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_died, | ||||
|     function(event) | ||||
|     function (event) | ||||
|         local player = game.get_player(event.player_index) | ||||
|  | ||||
|         if not player or not player.valid then | ||||
| @@ -1607,7 +1612,7 @@ Event.add( | ||||
|  | ||||
|         local cause = event.cause | ||||
|  | ||||
|         local message = {discord_bold_tag, player.name} | ||||
|         local message = { discord_bold_tag, player.name } | ||||
|         if cause and cause.valid then | ||||
|             message[#message + 1] = ' was killed by ' | ||||
|  | ||||
| @@ -1628,5 +1633,6 @@ Event.add( | ||||
| ) | ||||
|  | ||||
| Public.build_embed_data = build_embed_data | ||||
| Public.output_data = output_data | ||||
|  | ||||
| return Public | ||||
|   | ||||
							
								
								
									
										52
									
								
								utils/start.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								utils/start.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| local Event = require 'utils.event' | ||||
|  | ||||
| local Public = {} | ||||
|  | ||||
| local bp = | ||||
|     '0eNqlm91O20AUhN9lrx2UM7b3J69SocrAUiwlTuQYKEV59yYEF1RXqWe4QiE7Xud82fXq08mru1k/5l3fdoNbvbr2dtvt3erbq9u3P7pmffrf8LLLbuXaIW9c4bpmc3q1bze7dV7kbmiHl8VzOzwsts9d7t2hcG13l3+6lR2uC/c2oM3na55Hf+8eNzfHkSv7/9UKt9vujxfYdqc7OV4UV3XhXo5/y6v6ONVd2+fb89u+cE9N3zbnV3YoJvNBmS99YcLyCx+wNH6+6isf8P8THnEO7fqd5d+XeS/S4c8t9Pm+7fLd4viNuu3zkN3phv+dqqRULaX8R2rG6ECNjtTopNx/uZRSxqVKiWYp0SwnXPbDtsuLXTM8XBgfyPGRHJ+48Z+5zBpPEqkkItVkpVy+t2rC4qH51fQfkyzW+X64kAxyMqrJ+ZWvpMrXUuXryVq4fG/1hNTcKtTkeqgn329upvn1rqV6e6nenqy3l+vtyf3Kk3w8uV95macneXqJZ5B4BpJnkHkGkmcgeQaSZ5B5BpJnkHhGiWckeUbyyRVJipGkGEmKkTxFRJJdlNgliV0i2SX5FJHkU0SSTxGJrHySKm9LqfRjbHbtx4CwEY7RwM6V5LnmV30MsGU3rezGlt30shu5dY2BwAYiG0jypyHAmgZWEw4GFix0sGA5QS872LJrYsA0M2AlW/ZSfoZYKT9ErJSfIsZqANM8gGkiYIzNB8CqA6vYbaxil0fFbmMVeQgz1iiYphRMcwrGSgXTrcIY9Xo06NGoR5McJbBrZsOmamPO8Pm4dalhrNUwVmsY6zXMs6uX9Rk2FRoXeQQOH6swLLBbbtDXKGsxjNUYFlh8rL6wwOGLHD7WWFjUVx9rL4zVF8b6C2MFhrEGwyKHT3MXxsqLMaBg1MWH6ebDdPUxRpMcJXBr3gSaNwHrTbAkN98x4NlAYAORDSQyMB8iNAsDzcKAtTDQLQxMXrswee3C5LUL3dGAdTTQHA3EphDW0UB3NAC7iqHDBrs8WakDTepAkzpgpc4YUDixXSLQLRDYjhGwLSNgZRE0WQRNFoGVRWBlEVhZBFYWgZVFYGURWFkETRZBk0VgZRF0WQRdFkGXRahZxLoiAquIoCkiaN0vYFURPLtiWUEEr4NlVRH0Hhiw0ghaFwy0NhiwEgl6Iwx0nYSgww76EVhvlQErm6A1y0DrlgErn8D2y4BVTmCVE1jlBFY5gVVO0LpmoKknJK27PWnt7Ynrb09cg3viOtyT1uKetB73OWrpujj/gmX16QcvhXvK/f7tQohWhYQQfVqWy+pw+A3SPoD5' | ||||
|  | ||||
| function Public.blueprint(surface) | ||||
|     local position = {x = 0, y = 0} | ||||
|     if not surface or not surface.valid then | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     local item = surface.create_entity {name = 'item-on-ground', position = position, stack = {name = 'blueprint', count = 1}} | ||||
|     if not item then | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     local success = item.stack.import_stack(bp) | ||||
|     if success <= 0 then | ||||
|         local ghosts = item.stack.build_blueprint {surface = surface, force = 'player', position = position, force_build = true} | ||||
|         for _, ghost in pairs(ghosts) do | ||||
|             local _, ent = ghost.silent_revive({raise_revive = true}) | ||||
|             if ent and ent.valid then | ||||
|                 ent.destructible = false | ||||
|                 ent.minable = false | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     if item.valid then | ||||
|         item.destroy() | ||||
|     end | ||||
| end | ||||
|  | ||||
| Event.add( | ||||
|     defines.events.on_player_created, | ||||
|     function(event) | ||||
|         if event.player_index ~= 1 then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local player = game.get_player(event.player_index) | ||||
|         if not player or not player.valid then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         Public.blueprint(player.surface) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| return Public | ||||
| @@ -2,7 +2,6 @@ | ||||
|  | ||||
| local Token = require 'utils.token' | ||||
| local Task = require 'utils.task' | ||||
| local Alert = require 'utils.alert' | ||||
|  | ||||
| local Public = {} | ||||
|  | ||||
| @@ -19,39 +18,4 @@ Public.set_queue_speed = Task.set_queue_speed | ||||
| Public.delay = Task.queue_task | ||||
| Public.priority_delay = Task.set_timeout_in_ticks | ||||
|  | ||||
| local delay_print_alert_token = | ||||
|     Token.register( | ||||
|     function(event) | ||||
|         local text = event.text | ||||
|         if not text then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         local ttl = event.ttl | ||||
|         if not ttl then | ||||
|             ttl = 60 | ||||
|         end | ||||
|  | ||||
|         local sprite = event.sprite | ||||
|         local color = event.color | ||||
|  | ||||
|         Alert.alert_all_players(ttl, text, color, sprite, 1) | ||||
|     end | ||||
| ) | ||||
|  | ||||
| Public.set_timeout_in_ticks_alert = function(delay, data) | ||||
|     if not data then | ||||
|         return error('Data was not provided', 2) | ||||
|     end | ||||
|     if type(data) ~= 'table' then | ||||
|         return error("Data must be of type 'table'", 2) | ||||
|     end | ||||
|  | ||||
|     if not delay then | ||||
|         return error('No delay was provided', 2) | ||||
|     end | ||||
|  | ||||
|     Task.set_timeout_in_ticks(delay, delay_print_alert_token, data) | ||||
| end | ||||
|  | ||||
| return Public | ||||
|   | ||||
							
								
								
									
										2
									
								
								utils/templates/Vanilla/map_loader.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								utils/templates/Vanilla/map_loader.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| require 'utils.start' | ||||
| require 'utils.freeplay'.set('disabled', false) | ||||
		Reference in New Issue
	
	Block a user