From 2dc8f07ccf739cec8161a3b366084603ac78e265 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 22 Mar 2019 22:41:21 +0000 Subject: [PATCH 01/18] Added Chat Popups --- config/file_loader.lua | 2 ++ locale/en/addons.cfg | 3 ++ .../en/{commands-local.cfg => commands.cfg} | 0 modules/addons/addons.cfg | 3 ++ modules/addons/chat-popups.lua | 30 +++++++++++++++++++ .../{commands-local.cfg => commands.cfg} | 0 old/modules/{ => DONE}/ChatPopup/control.lua | 0 old/modules/{ => DONE}/ChatPopup/softmod.json | 0 8 files changed, 38 insertions(+) create mode 100644 locale/en/addons.cfg rename locale/en/{commands-local.cfg => commands.cfg} (100%) create mode 100644 modules/addons/addons.cfg create mode 100644 modules/addons/chat-popups.lua rename modules/commands/{commands-local.cfg => commands.cfg} (100%) rename old/modules/{ => DONE}/ChatPopup/control.lua (100%) rename old/modules/{ => DONE}/ChatPopup/softmod.json (100%) diff --git a/config/file_loader.lua b/config/file_loader.lua index 56005d6a..8eb1c26a 100644 --- a/config/file_loader.lua +++ b/config/file_loader.lua @@ -14,6 +14,8 @@ return { 'modules.commands.cheat-mode', 'modules.commands.interface', 'modules.commands.help', + -- QoL Addons + 'modules.addons.chat-popups', -- Config Files 'config.command_auth_admin', -- commands tags with admin_only are blocked for non admins 'config.permission_groups', -- loads some predefined permission groups diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg new file mode 100644 index 00000000..409e71a0 --- /dev/null +++ b/locale/en/addons.cfg @@ -0,0 +1,3 @@ +[chat-popup] +message=__1__: __2__ +ping=You have been mentioned in chat by __1__. \ No newline at end of file diff --git a/locale/en/commands-local.cfg b/locale/en/commands.cfg similarity index 100% rename from locale/en/commands-local.cfg rename to locale/en/commands.cfg diff --git a/modules/addons/addons.cfg b/modules/addons/addons.cfg new file mode 100644 index 00000000..409e71a0 --- /dev/null +++ b/modules/addons/addons.cfg @@ -0,0 +1,3 @@ +[chat-popup] +message=__1__: __2__ +ping=You have been mentioned in chat by __1__. \ No newline at end of file diff --git a/modules/addons/chat-popups.lua b/modules/addons/chat-popups.lua new file mode 100644 index 00000000..3a0592d3 --- /dev/null +++ b/modules/addons/chat-popups.lua @@ -0,0 +1,30 @@ +--- Creates flying text entities when a player sends a message in chat +-- also displays a ping above users who are named in the message +local Game = require 'utils.game' +local Event = require 'utils.event' + +local send_text = Game.print_player_floating_text -- (player_index, text, color) + +Event.add(defines.events.on_console_chat,function(event) + local player = Game.get_player_by_index(event.player_index) + + -- Some basic sanity checks + if not player then return end + if not event.message then return end + + -- Sends the message as text above them + send_text(player.index,{'chat-popup.message',player.name,event.message},player.chat_color) + + -- Makes lower and removes white space from the message + local search_string = event.message:lower():gsub("%s+", "") + + -- Loops over online players to see if they name is included + for _,mentioned_player in pairs(game.connected_players) do + if mentioned_player.index ~= player.index then + if search_string:match(mentioned_player.name:lower()) then + send_text(mentioned_player.index,{'chat-popup.ping',player.name},player.chat_color) + end + end + end + +end) \ No newline at end of file diff --git a/modules/commands/commands-local.cfg b/modules/commands/commands.cfg similarity index 100% rename from modules/commands/commands-local.cfg rename to modules/commands/commands.cfg diff --git a/old/modules/ChatPopup/control.lua b/old/modules/DONE/ChatPopup/control.lua similarity index 100% rename from old/modules/ChatPopup/control.lua rename to old/modules/DONE/ChatPopup/control.lua diff --git a/old/modules/ChatPopup/softmod.json b/old/modules/DONE/ChatPopup/softmod.json similarity index 100% rename from old/modules/ChatPopup/softmod.json rename to old/modules/DONE/ChatPopup/softmod.json From 29c542f391bd33234fe29a4e17bdb664161964a2 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 22 Mar 2019 23:02:10 +0000 Subject: [PATCH 02/18] Added Damage Popups --- config/file_loader.lua | 1 + config/popup_messages.lua | 7 ++++++ modules/addons/addons.cfg | 6 ++++- modules/addons/chat-popups.lua | 7 +++++- modules/addons/damage-popups.lua | 25 +++++++++++++++++++ .../{ => DONE}/DamagePopup/control.lua | 0 .../{ => DONE}/DamagePopup/softmod.json | 0 7 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 config/popup_messages.lua create mode 100644 modules/addons/damage-popups.lua rename old/modules/{ => DONE}/DamagePopup/control.lua (100%) rename old/modules/{ => DONE}/DamagePopup/softmod.json (100%) diff --git a/config/file_loader.lua b/config/file_loader.lua index 8eb1c26a..79f42801 100644 --- a/config/file_loader.lua +++ b/config/file_loader.lua @@ -16,6 +16,7 @@ return { 'modules.commands.help', -- QoL Addons 'modules.addons.chat-popups', + 'modules.addons.damage-popups', -- Config Files 'config.command_auth_admin', -- commands tags with admin_only are blocked for non admins 'config.permission_groups', -- loads some predefined permission groups diff --git a/config/popup_messages.lua b/config/popup_messages.lua new file mode 100644 index 00000000..a733c30a --- /dev/null +++ b/config/popup_messages.lua @@ -0,0 +1,7 @@ +--- A combination of config settings for different popup values like chat and damage +return { + show_player_messages=true, -- weather a message in chat will make a popup above them + show_player_mentions=true, -- weather a mentioned player will have a popup when mentioned in chat + show_player_damage=true, -- weather to show damage done by players + show_player_health=true -- weather to show player health when attacked +} \ No newline at end of file diff --git a/modules/addons/addons.cfg b/modules/addons/addons.cfg index 409e71a0..a4bb08a6 100644 --- a/modules/addons/addons.cfg +++ b/modules/addons/addons.cfg @@ -1,3 +1,7 @@ [chat-popup] message=__1__: __2__ -ping=You have been mentioned in chat by __1__. \ No newline at end of file +ping=You have been mentioned in chat by __1__. + +[damage-popup] +player-health=__1__ +player-damage=__1__ \ No newline at end of file diff --git a/modules/addons/chat-popups.lua b/modules/addons/chat-popups.lua index 3a0592d3..7c75dbf7 100644 --- a/modules/addons/chat-popups.lua +++ b/modules/addons/chat-popups.lua @@ -2,6 +2,7 @@ -- also displays a ping above users who are named in the message local Game = require 'utils.game' local Event = require 'utils.event' +local config = require 'config.popup_messages' local send_text = Game.print_player_floating_text -- (player_index, text, color) @@ -13,7 +14,11 @@ Event.add(defines.events.on_console_chat,function(event) if not event.message then return end -- Sends the message as text above them - send_text(player.index,{'chat-popup.message',player.name,event.message},player.chat_color) + if config.show_player_messages then + send_text(player.index,{'chat-popup.message',player.name,event.message},player.chat_color) + end + + if not config.show_player_mentions then return end -- Makes lower and removes white space from the message local search_string = event.message:lower():gsub("%s+", "") diff --git a/modules/addons/damage-popups.lua b/modules/addons/damage-popups.lua new file mode 100644 index 00000000..bb365ac9 --- /dev/null +++ b/modules/addons/damage-popups.lua @@ -0,0 +1,25 @@ +--- Displays the amount of dmg that is done by players to entities +-- also shows player health when a player is attacked +local Game = require 'utils.game' +local Event = require 'utils.event' +local config = require 'config.popup_messages' + +Event.add(defines.events.on_entity_damaged, function(event) + local entity = event.entity + local cause = event.cause + local damage = event.original_damage_amount + local health = entity.health + local health_percentage = entity.get_health_ratio() + local text_colour = {r=1-health_percentage,g=health_percentage,b=0} + + -- Checks if its a player and show player health is enabled + if entity.name == 'player' and config.show_player_health then + Game.print_player_floating_text(entity.index,{'damage-popup.player-health',health},text_colour) + end + + -- Checks if the source was a player and the entity was not a player + if entity.name ~= 'player' and cause and cause.name == 'player' and config.show_player_damage then + Game.print_floating_text(entity.surface,entity.position,{'damage-popup.player-damage',damage},text_colour) + end + +end) \ No newline at end of file diff --git a/old/modules/DamagePopup/control.lua b/old/modules/DONE/DamagePopup/control.lua similarity index 100% rename from old/modules/DamagePopup/control.lua rename to old/modules/DONE/DamagePopup/control.lua diff --git a/old/modules/DamagePopup/softmod.json b/old/modules/DONE/DamagePopup/softmod.json similarity index 100% rename from old/modules/DamagePopup/softmod.json rename to old/modules/DONE/DamagePopup/softmod.json From 40de1fd59bd7b724059f1026691786b500d62d4d Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 22 Mar 2019 23:03:02 +0000 Subject: [PATCH 03/18] Fixed Locale --- locale/en/addons.cfg | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index 409e71a0..a4bb08a6 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -1,3 +1,7 @@ [chat-popup] message=__1__: __2__ -ping=You have been mentioned in chat by __1__. \ No newline at end of file +ping=You have been mentioned in chat by __1__. + +[damage-popup] +player-health=__1__ +player-damage=__1__ \ No newline at end of file From 44880ffe87ae409c299722c8d1aba6ea0a321ef6 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 22 Mar 2019 23:34:02 +0000 Subject: [PATCH 04/18] Added some varience to the location --- config/popup_messages.lua | 3 ++- modules/addons/damage-popups.lua | 29 ++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/config/popup_messages.lua b/config/popup_messages.lua index a733c30a..bee5b53c 100644 --- a/config/popup_messages.lua +++ b/config/popup_messages.lua @@ -3,5 +3,6 @@ return { show_player_messages=true, -- weather a message in chat will make a popup above them show_player_mentions=true, -- weather a mentioned player will have a popup when mentioned in chat show_player_damage=true, -- weather to show damage done by players - show_player_health=true -- weather to show player health when attacked + show_player_health=true, -- weather to show player health when attacked + damage_location_variance=0.8 -- how close to the eade of an entity the popups will appear } \ No newline at end of file diff --git a/modules/addons/damage-popups.lua b/modules/addons/damage-popups.lua index bb365ac9..4233ac1d 100644 --- a/modules/addons/damage-popups.lua +++ b/modules/addons/damage-popups.lua @@ -7,19 +7,34 @@ local config = require 'config.popup_messages' Event.add(defines.events.on_entity_damaged, function(event) local entity = event.entity local cause = event.cause - local damage = event.original_damage_amount - local health = entity.health + local damage = math.floor(event.original_damage_amount) + local health = math.floor(entity.health) local health_percentage = entity.get_health_ratio() local text_colour = {r=1-health_percentage,g=health_percentage,b=0} - -- Checks if its a player and show player health is enabled + -- Gets the location of the text + local size = entity.get_radius() + if size < 1 then size = 1 end + local r = (math.random()-0.5)*size*config.damage_location_variance + local p = entity.position + local position = {x=p.x+r,y=p.y-size} + + -- Sets the message + local message if entity.name == 'player' and config.show_player_health then - Game.print_player_floating_text(entity.index,{'damage-popup.player-health',health},text_colour) + message = {'damage-popup.player-health',health} + elseif entity.name ~= 'player' and cause and cause.name == 'player' and config.show_player_damage then + message = {'damage-popup.player-damage',damage} end - -- Checks if the source was a player and the entity was not a player - if entity.name ~= 'player' and cause and cause.name == 'player' and config.show_player_damage then - Game.print_floating_text(entity.surface,entity.position,{'damage-popup.player-damage',damage},text_colour) + -- Outputs the message as floating text + if message then + Game.print_floating_text( + entity.surface, + position, + message, + text_colour + ) end end) \ No newline at end of file From 06b4ae9b25d2173a93e2e8dbb3a88e7985b53644 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 24 Mar 2019 15:38:27 +0000 Subject: [PATCH 05/18] Moved ExpGamingLib --- old/modules/DONE/ExpGamingLib/control.lua | 330 +++++++++++++++++++++ old/modules/DONE/ExpGamingLib/softmod.json | 19 ++ 2 files changed, 349 insertions(+) create mode 100644 old/modules/DONE/ExpGamingLib/control.lua create mode 100644 old/modules/DONE/ExpGamingLib/softmod.json diff --git a/old/modules/DONE/ExpGamingLib/control.lua b/old/modules/DONE/ExpGamingLib/control.lua new file mode 100644 index 00000000..77b4685c --- /dev/null +++ b/old/modules/DONE/ExpGamingLib/control.lua @@ -0,0 +1,330 @@ +--- Adds some common functions used though out all ExpGaming modules +-- @module ExpGamingLib +-- @alias ExpLib +-- @author Cooldude2606 +-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE + +local Game = require('FactorioStdLib.Game') +local Color = require('FactorioStdLib.Color') + +local module_verbose = false -- there is no verbose in this file so true will do nothing +local ExpLib = {} + +--- Loads a table into _G even when sandboxes; will not overwrite values or append to tables; will not work during runtime to avoid desyncs +-- @usage unpack_to_G{key1='foo',key2='bar'} +-- @tparam table tbl table to be unpacked +function ExpLib.unpack_to_G(tbl) + if not type(tbl) == 'table' or game then return end + for key,value in pairs(tbl) do + if not _G[key] then rawset(_G,key,value) end + end +end + +--- Used to get the current ENV with all _G keys removed; useful when saving function to global +-- @usage get_env() returns current ENV with _G keys removed +-- @treturn table the env table with _G keys removed +-- @warning does not work from console +function ExpLib.get_env(level) + level = level and level+1 or 2 + local env = setmetatable({},{__index=_G}) + while true do + if not debug.getinfo(level) then break end + local i = 1 + while true do + local name, value = debug.getlocal(level,i) + if not name or _G[name] == value then break else env[name] = value end + i=i+1 + end + level=level+1 + end + return env +end + +--- Used to get the current ENV with all _G keys removed; useful when saving function to global +-- @usage get_env() returns current ENV with _G keys removed +-- @treturn table the env table with _G keys removed +-- @warning does not work from console +function ExpLib.get_upvalues(level) + local func = level and ExpLib.is_type(level,'function') and level or nil + level = level and ExpLib.is_type(level,'number') and level+1 or 2 + func = func or debug.getinfo(level).func + local upvalues = setmetatable({},{__index=_G}) + local i = 1 + while true do + local name, value = debug.getupvalue(func,i) + if not name then break else upvalues[name] = value end + i=i+1 + end + return upvalues +end + +--- Creates a table that will act like a string and a function +-- @usage add_metatable({},function) -- returns table +-- @tparam table tbl the table that will have its metatable set +-- @tparam[opt=tostring] function callback the function that will be used for the call +-- @tparam[opt=table.tostring] ?function|string string a function that resolves to a string or a string +-- @treturn table the new table with its metatable set +function ExpLib.add_metatable(tbl,callback,string) + if not ExpLib.is_type(tbl,'table') then error('No table given to add_metatable',2) end + callback = ExpLib.is_type(callback,'function') and callback or tostring + string = ExpLib.is_type(string,'function') and string or ExpLib.is_type(string,'string') and function() return string end or table.tostring + return setmetatable(tbl,{ + __tostring=string, + __concat=function(val1,val2) return type(val1) == 'string' and val1..string(val2) or string(val1)..val2 end, + __call=callback + }) +end + +--- Compare types faster for faster validation of prams +-- @usage is_type('foo','string') -- return true +-- @usage is_type('foo') -- return false +-- @param v the value to be tested +-- @tparam[opt=nil] string test_type the type to test for if not given then it tests for nil +-- @treturn boolean is v of type test_type +function ExpLib.is_type(v,test_type) + return test_type and v and type(v) == test_type or not test_type and not v or false +end + +--- Compare types faster for faster validation of prams, including giving an error if incorrect +-- @usage type_error('foo','string','Value is not a string') -- return true +-- @usage type_error('foo','table','Value is not a string') -- return error +-- @param value the value to be tested +-- @tparam[opt=nil] string type the type that the value should be +-- @tparam string error_message the message given when type is not matched +-- @treturn boolean if it matched or and error +function ExpLib.type_error(value,type,error_message) + return ExpLib.is_type(value,type) or error(error_message,3) +end + +--- A specialised version of type_error to test for self +-- @usage self_test(self,'Object','get_name') +-- @tparam table self the table that is the object +-- @tparam string prototype_name the name of the class +-- @tparam string function_name the name of the function +function ExpLib.self_test(self,prototype_name,function_name) + return ExpLib.is_type(self,'table') or error('Call to prototype without context, either supply a '..prototype_name..' or use '..prototype_name..':'..function_name,3) +end + +--- Will return a value of any type to the player/server console, allows colour for in-game players +-- @usage player_return('Hello, World!') -- returns 'Hello, World!' to game.player or server console +-- @usage player_return('Hello, World!','green') -- returns 'Hello, World!' to game.player with colour green or server console +-- @usage player_return('Hello, World!',nil,player) -- returns 'Hello, World!' to the given player +-- @param rtn any value of any type that will be returned to the player or console +-- @tparam[opt=defines.colour.white] ?defines.color|string colour the colour of the text for the player, ignored when printing to console +-- @tparam[opt=game.player] LuaPlayer player the player that return will go to, if no game.player then returns to server +function ExpLib.player_return(rtn,colour,player) + colour = ExpLib.is_type(colour,'table') and colour or defines.textcolor[colour] ~= defines.color.white and defines.textcolor[colour] or defines.color[colour] + player = player or game.player + -- converts the value to a string + local returnAsString + if ExpLib.is_type(rtn,'table') then + if ExpLib.is_type(rtn.__self,'userdata') then + -- value is userdata + returnAsString = 'Cant Display Userdata' + elseif ExpLib.is_type(rtn[1],'string') and string.find(rtn[1],'.+[.].+') and not string.find(rtn[1],'%s') then + -- value is a locale string + returnAsString = rtn + elseif getmetatable(rtn) ~= nil and not tostring(rtn):find('table: 0x') then + -- value has a tostring meta method + returnAsString = tostring(rtn) + else + -- value is a table + returnAsString = table.tostring(rtn) + end + elseif ExpLib.is_type(rtn,'function') then + -- value is a function + returnAsString = 'Cant Display Functions' + else returnAsString = tostring(rtn) end + -- returns to the player or the server + if player then + -- allows any valid player identifier to be used + player = Game.get_player(player) + if not player then error('Invalid Player given to player_return',2) end + -- plays a nice sound that is different to normal message sound + player.play_sound{path='utility/scenario_message'} + player.print(returnAsString,colour) + else rcon.print(returnAsString) end +end + +--- Convert ticks to hours +-- @usage tick_to_hour(216001) -- return 1 +-- @tparam number tick tick to convert to hours +-- @treturn number the number of whole hours from this tick +function ExpLib.tick_to_hour(tick) + if not ExpLib.is_type(tick,'number') then return 0 end + if not game then return math.floor(tick/216000) end + return math.floor(tick/(216000*game.speed)) +end + +--- Convert ticks to minutes +-- @usage tick_to_hour(3601) -- return 1 +-- @tparam number tick tick to convert to minutes +-- @treturn number the number of whole minutes from this tick +function ExpLib.tick_to_min (tick) + if not ExpLib.is_type(tick,'number') then return 0 end + if not game then return math.floor(tick/3600) end + return math.floor(tick/(3600*game.speed)) +end + +--- Converts a tick into a clean format for end user +-- @usage tick_to_display_format(3600) -- return '1.00 M' +-- @usage tick_to_display_format(234000) -- return '1 H 5 M' +-- @tparam number tick the tick to convert +-- @treturn string the formated string +function ExpLib.tick_to_display_format(tick) + if not ExpLib.is_type(tick,'number') then return '0H 0M' end + if ExpLib.tick_to_min(tick) < 10 then + if not game then return math.floor(tick/3600) end + return string.format('%.2f M',tick/(3600*game.speed)) + else + return string.format('%d H %d M', + ExpLib.tick_to_hour(tick), + ExpLib.tick_to_min(tick)-60*ExpLib.tick_to_hour(tick) + ) + end +end + +--- Used as a way to view the structure of a gui, used for debugging +-- @usage Gui_tree(root) returns all children of gui recursively +-- @tparam LuaGuiElement root the root to start the tree from +-- @treturn table the table that describes the gui +function ExpLib.gui_tree(root) + if not ExpLib.is_type(root,'table') or not root.valid then error('Invalid Gui Element given to gui_tree',2) end + local tree = {} + for _,child in pairs(root.children) do + if #child.children > 0 then + if child.name then tree[child.name] = ExpLib.gui_tree(child) + else table.insert(tree,ExpLib.gui_tree(child)) end + else + if child.name then tree[child.name] = child.type + else table.insert(tree,child.type) end + end + end + return tree +end + +--- Extents the table class +-- @type table +-- @alias table + +--- Returns a value in a form able to be read as a value, any value to string +-- @usage table.val_to_str{a='foo'} -- return '"foo"' +-- @param v value to convert +-- @treturn string the converted value +function table.val_to_str(v) + if "string" == type( v ) then + v = string.gsub(v,"\n","\\n") + if string.match(string.gsub(v,"[^'\"]",""),'^"+$') then + return "'"..v.."'" + end + return '"'..string.gsub(v,'"', '\\"' )..'"' + else + return "table" == type( v) and table.tostring(v) or + "function" == type(v) and '"cant-display-function"' or + "userdata" == type(v) and '"cant-display-userdata"' or + tostring(v) + end +end + +--- Returns a value in a form able to be read as a key, any key to string +-- @usage table.val_to_str{a='foo'} -- return '["a"]' +-- @param k key to convert +-- @treturn string the converted key +function table.key_to_str (k) + if "string" == type(k) and string.match(k,"^[_%player][_%player%d]*$") then + return k + else + return "["..table.val_to_str(k).."]" + end +end + +--- Returns a table in a form able to be read as a table +-- @usage table.tostring{k1='foo',k2='bar'} -- return '{["k1"]="foo",["k2"]="bar"}' +-- @tparam table tbl table to convert +-- @treturn string the converted table +function table.tostring(tbl) + if type(tbl) ~= 'table' then return tostring(tbl) end + local result, done = {}, {} + for k, v in ipairs(tbl) do + table.insert(result,table.val_to_str(v)) + done[k] = true + end + for k, v in pairs(tbl) do + if not done[k] then + table.insert(result, + table.key_to_str(k).."="..table.val_to_str(v)) + end + end + return "{"..table.concat(result,",") .."}" +end + +--- Similar to table.tostring but converts a lua table to a json one +-- @usage table.json{k1='foo',k2='bar'} -- return '{"k1":"foo","k2":"bar"}' +-- @tparam table lua_table the table to convert +-- @treturn string the table in a json format +function table.json(lua_table) + --if game and game.table_to_json then return game.table_to_json(lua_table) end + local result, done, only_indexes = {}, {}, true + for key,value in ipairs(lua_table) do + done[key] = true + if type(value) == 'table' then table.insert(result,table.json(value,true)) + elseif not value then table.insert(result,'null') + else table.insert(result,table.val_to_str(value)) + end + end + for key,value in pairs(lua_table) do + if not done[key] then + only_indexes = false + if type(value) == 'table' then table.insert(result,table.val_to_str(key)..':'..table.json(value,true)) + elseif not value then table.insert(result,table.val_to_str(key)..':null') + else table.insert(result,table.val_to_str(key)..':'..table.val_to_str(value)) + end + end + end + if only_indexes then return "["..table.concat(result,",").."]" + else return "{"..table.concat(result,",").."}" + end +end + +--- Returns the closest match to a key +-- @usage table.autokey({foo=1,bar=2},'f') -- return 1 +-- @tparam table tbl the table that will be searched +-- @tparam string str the string that will be looked for in the keys +function table.autokey(tbl,str) + if not ExpLib.is_type(str,'string') then return end + local _return = {} + for key,value in pairs(tbl) do + if string.contains(string.lower(key),string.lower(str)) then table.insert(_return,value) end + end + return _return[1] or false +end + +--- Returns the list is a sorted way that would be expected by people (this is by key) +-- @usage tbl = table.alphanumsort(tbl) +-- @tparam table tbl the table to be sorted +-- @treturn table the sorted table +function table.alphanumsort(tbl) + local o = table.keys(tbl) + local function padnum(d) local dec, n = string.match(d, "(%.?)0*(.+)") + return #dec > 0 and ("%.12f"):format(d) or ("%s%03d%s"):format(dec, #n, n) end + table.sort(o, function(a,b) + return tostring(a):gsub("%.?%d+",padnum)..("%3d"):format(#b) + < tostring(b):gsub("%.?%d+",padnum)..("%3d"):format(#a) end) + local _tbl = {} + for _,k in pairs(o) do _tbl[k] = tbl[k] end + return _tbl +end + +--- Returns the list is a sorted way that would be expected by people (this is by key) (faster alterative than above) +-- @usage tbl = table.alphanumsort(tbl) +-- @tparam table tbl the table to be sorted +-- @treturn table the sorted table +function table.keysort(tbl) + local o = table.keys(tbl,true) + local _tbl = {} + for _,k in pairs(o) do _tbl[k] = tbl[k] end + return _tbl +end + +ExpLib:unpack_to_G() +return ExpLib \ No newline at end of file diff --git a/old/modules/DONE/ExpGamingLib/softmod.json b/old/modules/DONE/ExpGamingLib/softmod.json new file mode 100644 index 00000000..160803be --- /dev/null +++ b/old/modules/DONE/ExpGamingLib/softmod.json @@ -0,0 +1,19 @@ +{ + "name": "ExpGamingLib", + "version": "4.0.0", + "description": "Adds some common functions used though out all ExpGaming modules", + "location": "FSM_ARCHIVE", + "keywords": [ + "ExpGaming", + "Lib" + ], + "author": "Cooldude2606", + "contact": "Discord: Cooldude2606#5241", + "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", + "dependencies": { + "FactorioStdLib.Game": "^0.8.0", + "FactorioStdLib.Color": "^0.8.0", + "FactorioStdLib.Table": "^0.8.0" + }, + "submodules": {} +} From 7c4210f8b48d821c1c90087d3e7c016264072451 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 24 Mar 2019 15:39:17 +0000 Subject: [PATCH 06/18] Added command_auth_runtime_disable --- config/command_auth_admin.lua | 2 +- config/command_auth_runtime_disable.lua | 25 ++ config/config.cfg | 3 + config/death_markers.lua | 12 + config/file_loader.lua | 3 +- locale/en/config.cfg | 3 + modules/addons/death-markers.lua | 7 + .../{ => DONE}/DeathMarkers/control.lua | 0 .../{ => DONE}/DeathMarkers/softmod.json | 0 old/modules/ExpGamingLib/control.lua | 330 ------------------ old/modules/ExpGamingLib/softmod.json | 19 - 11 files changed, 53 insertions(+), 351 deletions(-) create mode 100644 config/command_auth_runtime_disable.lua create mode 100644 config/config.cfg create mode 100644 config/death_markers.lua create mode 100644 locale/en/config.cfg create mode 100644 modules/addons/death-markers.lua rename old/modules/{ => DONE}/DeathMarkers/control.lua (100%) rename old/modules/{ => DONE}/DeathMarkers/softmod.json (100%) delete mode 100644 old/modules/ExpGamingLib/control.lua delete mode 100644 old/modules/ExpGamingLib/softmod.json diff --git a/config/command_auth_admin.lua b/config/command_auth_admin.lua index 4817e643..19ef9198 100644 --- a/config/command_auth_admin.lua +++ b/config/command_auth_admin.lua @@ -8,7 +8,7 @@ Commands.add_authenticator(function(player,command,tags,reject) if player.admin then return true else - return reject('This command is for admins only!') + return reject{'command-auth.admin-only'} end else return true diff --git a/config/command_auth_runtime_disable.lua b/config/command_auth_runtime_disable.lua new file mode 100644 index 00000000..0f4861fb --- /dev/null +++ b/config/command_auth_runtime_disable.lua @@ -0,0 +1,25 @@ +--- This config for command auth allows commands to be globally enabled and disabled during runtime +-- this config adds Commands.disable and Commands.enable to enable and disable commands for all users +local Commands = require 'expcore.commands' +local Global = require 'utils.global' + +local disabled_commands = {} +Global.register(disabled_commands,function(tbl) + disabled_commands = tbl +end) + +function Commands.disable(command_name) + disabled_commands[command_name] = true +end + +function Commands.enable(command_name) + disabled_commands[command_name] = nil +end + +Commands.add_authenticator(function(player,command,tags,reject) + if disabled_commands[command] then + return reject{'command-auth.command-disabled'} + else + return true + end +end) \ No newline at end of file diff --git a/config/config.cfg b/config/config.cfg new file mode 100644 index 00000000..b12b17cf --- /dev/null +++ b/config/config.cfg @@ -0,0 +1,3 @@ +[command-auth] +admin-only=This command is for (game) admins only! +command-disabled=This command has been disabled by management! \ No newline at end of file diff --git a/config/death_markers.lua b/config/death_markers.lua new file mode 100644 index 00000000..cb195cde --- /dev/null +++ b/config/death_markers.lua @@ -0,0 +1,12 @@ +--- This config controls what happens when a player dies mostly about map markers and item collection +-- allow_teleport_to_body_command and allow_collect_bodies_command can be over ridden if command_auth_runtime_disable is present +-- if not present then the commands will not be loaded into the game +return { + allow_teleport_to_body_command=false, -- allows use of /return-to-body which teleports you to your last death + allow_collect_bodies_command=false, -- allows use of /collect-body which returns all your items to you and removes the body + use_chests_as_bodies=false, -- weather items should be moved into a chest when a player dies + auto_collect_bodies=false, -- enables items being returned to the spawn point in chests upon death + show_map_markers=true, -- shows markers on the map where bodies are + include_time_of_death=true, -- weather to include the time of death on the map marker + map_icon='' -- the icon that the map marker shows '' means no icon +} \ No newline at end of file diff --git a/config/file_loader.lua b/config/file_loader.lua index 79f42801..c87e9d85 100644 --- a/config/file_loader.lua +++ b/config/file_loader.lua @@ -18,6 +18,7 @@ return { 'modules.addons.chat-popups', 'modules.addons.damage-popups', -- Config Files - 'config.command_auth_admin', -- commands tags with admin_only are blocked for non admins + 'config.command_auth_admin', -- commands tagged with admin_only are blocked for non admins + 'config.command_auth_runtime_disable', -- allows commands to be enabled and disabled during runtime 'config.permission_groups', -- loads some predefined permission groups } \ No newline at end of file diff --git a/locale/en/config.cfg b/locale/en/config.cfg new file mode 100644 index 00000000..b12b17cf --- /dev/null +++ b/locale/en/config.cfg @@ -0,0 +1,3 @@ +[command-auth] +admin-only=This command is for (game) admins only! +command-disabled=This command has been disabled by management! \ No newline at end of file diff --git a/modules/addons/death-markers.lua b/modules/addons/death-markers.lua new file mode 100644 index 00000000..616854b9 --- /dev/null +++ b/modules/addons/death-markers.lua @@ -0,0 +1,7 @@ +local Event = require 'utils.event' +local Game = require 'utils.game' +local Global = require 'utils.global' +local Commands = require 'expcore.commands' +local config = require 'config.death_markers' +local opt_require = ext_require('expcore.common','opt_require') +opt_require 'config.command_auth_runtime_disable' -- if the file is present then we can disable the commands \ No newline at end of file diff --git a/old/modules/DeathMarkers/control.lua b/old/modules/DONE/DeathMarkers/control.lua similarity index 100% rename from old/modules/DeathMarkers/control.lua rename to old/modules/DONE/DeathMarkers/control.lua diff --git a/old/modules/DeathMarkers/softmod.json b/old/modules/DONE/DeathMarkers/softmod.json similarity index 100% rename from old/modules/DeathMarkers/softmod.json rename to old/modules/DONE/DeathMarkers/softmod.json diff --git a/old/modules/ExpGamingLib/control.lua b/old/modules/ExpGamingLib/control.lua deleted file mode 100644 index 77b4685c..00000000 --- a/old/modules/ExpGamingLib/control.lua +++ /dev/null @@ -1,330 +0,0 @@ ---- Adds some common functions used though out all ExpGaming modules --- @module ExpGamingLib --- @alias ExpLib --- @author Cooldude2606 --- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE - -local Game = require('FactorioStdLib.Game') -local Color = require('FactorioStdLib.Color') - -local module_verbose = false -- there is no verbose in this file so true will do nothing -local ExpLib = {} - ---- Loads a table into _G even when sandboxes; will not overwrite values or append to tables; will not work during runtime to avoid desyncs --- @usage unpack_to_G{key1='foo',key2='bar'} --- @tparam table tbl table to be unpacked -function ExpLib.unpack_to_G(tbl) - if not type(tbl) == 'table' or game then return end - for key,value in pairs(tbl) do - if not _G[key] then rawset(_G,key,value) end - end -end - ---- Used to get the current ENV with all _G keys removed; useful when saving function to global --- @usage get_env() returns current ENV with _G keys removed --- @treturn table the env table with _G keys removed --- @warning does not work from console -function ExpLib.get_env(level) - level = level and level+1 or 2 - local env = setmetatable({},{__index=_G}) - while true do - if not debug.getinfo(level) then break end - local i = 1 - while true do - local name, value = debug.getlocal(level,i) - if not name or _G[name] == value then break else env[name] = value end - i=i+1 - end - level=level+1 - end - return env -end - ---- Used to get the current ENV with all _G keys removed; useful when saving function to global --- @usage get_env() returns current ENV with _G keys removed --- @treturn table the env table with _G keys removed --- @warning does not work from console -function ExpLib.get_upvalues(level) - local func = level and ExpLib.is_type(level,'function') and level or nil - level = level and ExpLib.is_type(level,'number') and level+1 or 2 - func = func or debug.getinfo(level).func - local upvalues = setmetatable({},{__index=_G}) - local i = 1 - while true do - local name, value = debug.getupvalue(func,i) - if not name then break else upvalues[name] = value end - i=i+1 - end - return upvalues -end - ---- Creates a table that will act like a string and a function --- @usage add_metatable({},function) -- returns table --- @tparam table tbl the table that will have its metatable set --- @tparam[opt=tostring] function callback the function that will be used for the call --- @tparam[opt=table.tostring] ?function|string string a function that resolves to a string or a string --- @treturn table the new table with its metatable set -function ExpLib.add_metatable(tbl,callback,string) - if not ExpLib.is_type(tbl,'table') then error('No table given to add_metatable',2) end - callback = ExpLib.is_type(callback,'function') and callback or tostring - string = ExpLib.is_type(string,'function') and string or ExpLib.is_type(string,'string') and function() return string end or table.tostring - return setmetatable(tbl,{ - __tostring=string, - __concat=function(val1,val2) return type(val1) == 'string' and val1..string(val2) or string(val1)..val2 end, - __call=callback - }) -end - ---- Compare types faster for faster validation of prams --- @usage is_type('foo','string') -- return true --- @usage is_type('foo') -- return false --- @param v the value to be tested --- @tparam[opt=nil] string test_type the type to test for if not given then it tests for nil --- @treturn boolean is v of type test_type -function ExpLib.is_type(v,test_type) - return test_type and v and type(v) == test_type or not test_type and not v or false -end - ---- Compare types faster for faster validation of prams, including giving an error if incorrect --- @usage type_error('foo','string','Value is not a string') -- return true --- @usage type_error('foo','table','Value is not a string') -- return error --- @param value the value to be tested --- @tparam[opt=nil] string type the type that the value should be --- @tparam string error_message the message given when type is not matched --- @treturn boolean if it matched or and error -function ExpLib.type_error(value,type,error_message) - return ExpLib.is_type(value,type) or error(error_message,3) -end - ---- A specialised version of type_error to test for self --- @usage self_test(self,'Object','get_name') --- @tparam table self the table that is the object --- @tparam string prototype_name the name of the class --- @tparam string function_name the name of the function -function ExpLib.self_test(self,prototype_name,function_name) - return ExpLib.is_type(self,'table') or error('Call to prototype without context, either supply a '..prototype_name..' or use '..prototype_name..':'..function_name,3) -end - ---- Will return a value of any type to the player/server console, allows colour for in-game players --- @usage player_return('Hello, World!') -- returns 'Hello, World!' to game.player or server console --- @usage player_return('Hello, World!','green') -- returns 'Hello, World!' to game.player with colour green or server console --- @usage player_return('Hello, World!',nil,player) -- returns 'Hello, World!' to the given player --- @param rtn any value of any type that will be returned to the player or console --- @tparam[opt=defines.colour.white] ?defines.color|string colour the colour of the text for the player, ignored when printing to console --- @tparam[opt=game.player] LuaPlayer player the player that return will go to, if no game.player then returns to server -function ExpLib.player_return(rtn,colour,player) - colour = ExpLib.is_type(colour,'table') and colour or defines.textcolor[colour] ~= defines.color.white and defines.textcolor[colour] or defines.color[colour] - player = player or game.player - -- converts the value to a string - local returnAsString - if ExpLib.is_type(rtn,'table') then - if ExpLib.is_type(rtn.__self,'userdata') then - -- value is userdata - returnAsString = 'Cant Display Userdata' - elseif ExpLib.is_type(rtn[1],'string') and string.find(rtn[1],'.+[.].+') and not string.find(rtn[1],'%s') then - -- value is a locale string - returnAsString = rtn - elseif getmetatable(rtn) ~= nil and not tostring(rtn):find('table: 0x') then - -- value has a tostring meta method - returnAsString = tostring(rtn) - else - -- value is a table - returnAsString = table.tostring(rtn) - end - elseif ExpLib.is_type(rtn,'function') then - -- value is a function - returnAsString = 'Cant Display Functions' - else returnAsString = tostring(rtn) end - -- returns to the player or the server - if player then - -- allows any valid player identifier to be used - player = Game.get_player(player) - if not player then error('Invalid Player given to player_return',2) end - -- plays a nice sound that is different to normal message sound - player.play_sound{path='utility/scenario_message'} - player.print(returnAsString,colour) - else rcon.print(returnAsString) end -end - ---- Convert ticks to hours --- @usage tick_to_hour(216001) -- return 1 --- @tparam number tick tick to convert to hours --- @treturn number the number of whole hours from this tick -function ExpLib.tick_to_hour(tick) - if not ExpLib.is_type(tick,'number') then return 0 end - if not game then return math.floor(tick/216000) end - return math.floor(tick/(216000*game.speed)) -end - ---- Convert ticks to minutes --- @usage tick_to_hour(3601) -- return 1 --- @tparam number tick tick to convert to minutes --- @treturn number the number of whole minutes from this tick -function ExpLib.tick_to_min (tick) - if not ExpLib.is_type(tick,'number') then return 0 end - if not game then return math.floor(tick/3600) end - return math.floor(tick/(3600*game.speed)) -end - ---- Converts a tick into a clean format for end user --- @usage tick_to_display_format(3600) -- return '1.00 M' --- @usage tick_to_display_format(234000) -- return '1 H 5 M' --- @tparam number tick the tick to convert --- @treturn string the formated string -function ExpLib.tick_to_display_format(tick) - if not ExpLib.is_type(tick,'number') then return '0H 0M' end - if ExpLib.tick_to_min(tick) < 10 then - if not game then return math.floor(tick/3600) end - return string.format('%.2f M',tick/(3600*game.speed)) - else - return string.format('%d H %d M', - ExpLib.tick_to_hour(tick), - ExpLib.tick_to_min(tick)-60*ExpLib.tick_to_hour(tick) - ) - end -end - ---- Used as a way to view the structure of a gui, used for debugging --- @usage Gui_tree(root) returns all children of gui recursively --- @tparam LuaGuiElement root the root to start the tree from --- @treturn table the table that describes the gui -function ExpLib.gui_tree(root) - if not ExpLib.is_type(root,'table') or not root.valid then error('Invalid Gui Element given to gui_tree',2) end - local tree = {} - for _,child in pairs(root.children) do - if #child.children > 0 then - if child.name then tree[child.name] = ExpLib.gui_tree(child) - else table.insert(tree,ExpLib.gui_tree(child)) end - else - if child.name then tree[child.name] = child.type - else table.insert(tree,child.type) end - end - end - return tree -end - ---- Extents the table class --- @type table --- @alias table - ---- Returns a value in a form able to be read as a value, any value to string --- @usage table.val_to_str{a='foo'} -- return '"foo"' --- @param v value to convert --- @treturn string the converted value -function table.val_to_str(v) - if "string" == type( v ) then - v = string.gsub(v,"\n","\\n") - if string.match(string.gsub(v,"[^'\"]",""),'^"+$') then - return "'"..v.."'" - end - return '"'..string.gsub(v,'"', '\\"' )..'"' - else - return "table" == type( v) and table.tostring(v) or - "function" == type(v) and '"cant-display-function"' or - "userdata" == type(v) and '"cant-display-userdata"' or - tostring(v) - end -end - ---- Returns a value in a form able to be read as a key, any key to string --- @usage table.val_to_str{a='foo'} -- return '["a"]' --- @param k key to convert --- @treturn string the converted key -function table.key_to_str (k) - if "string" == type(k) and string.match(k,"^[_%player][_%player%d]*$") then - return k - else - return "["..table.val_to_str(k).."]" - end -end - ---- Returns a table in a form able to be read as a table --- @usage table.tostring{k1='foo',k2='bar'} -- return '{["k1"]="foo",["k2"]="bar"}' --- @tparam table tbl table to convert --- @treturn string the converted table -function table.tostring(tbl) - if type(tbl) ~= 'table' then return tostring(tbl) end - local result, done = {}, {} - for k, v in ipairs(tbl) do - table.insert(result,table.val_to_str(v)) - done[k] = true - end - for k, v in pairs(tbl) do - if not done[k] then - table.insert(result, - table.key_to_str(k).."="..table.val_to_str(v)) - end - end - return "{"..table.concat(result,",") .."}" -end - ---- Similar to table.tostring but converts a lua table to a json one --- @usage table.json{k1='foo',k2='bar'} -- return '{"k1":"foo","k2":"bar"}' --- @tparam table lua_table the table to convert --- @treturn string the table in a json format -function table.json(lua_table) - --if game and game.table_to_json then return game.table_to_json(lua_table) end - local result, done, only_indexes = {}, {}, true - for key,value in ipairs(lua_table) do - done[key] = true - if type(value) == 'table' then table.insert(result,table.json(value,true)) - elseif not value then table.insert(result,'null') - else table.insert(result,table.val_to_str(value)) - end - end - for key,value in pairs(lua_table) do - if not done[key] then - only_indexes = false - if type(value) == 'table' then table.insert(result,table.val_to_str(key)..':'..table.json(value,true)) - elseif not value then table.insert(result,table.val_to_str(key)..':null') - else table.insert(result,table.val_to_str(key)..':'..table.val_to_str(value)) - end - end - end - if only_indexes then return "["..table.concat(result,",").."]" - else return "{"..table.concat(result,",").."}" - end -end - ---- Returns the closest match to a key --- @usage table.autokey({foo=1,bar=2},'f') -- return 1 --- @tparam table tbl the table that will be searched --- @tparam string str the string that will be looked for in the keys -function table.autokey(tbl,str) - if not ExpLib.is_type(str,'string') then return end - local _return = {} - for key,value in pairs(tbl) do - if string.contains(string.lower(key),string.lower(str)) then table.insert(_return,value) end - end - return _return[1] or false -end - ---- Returns the list is a sorted way that would be expected by people (this is by key) --- @usage tbl = table.alphanumsort(tbl) --- @tparam table tbl the table to be sorted --- @treturn table the sorted table -function table.alphanumsort(tbl) - local o = table.keys(tbl) - local function padnum(d) local dec, n = string.match(d, "(%.?)0*(.+)") - return #dec > 0 and ("%.12f"):format(d) or ("%s%03d%s"):format(dec, #n, n) end - table.sort(o, function(a,b) - return tostring(a):gsub("%.?%d+",padnum)..("%3d"):format(#b) - < tostring(b):gsub("%.?%d+",padnum)..("%3d"):format(#a) end) - local _tbl = {} - for _,k in pairs(o) do _tbl[k] = tbl[k] end - return _tbl -end - ---- Returns the list is a sorted way that would be expected by people (this is by key) (faster alterative than above) --- @usage tbl = table.alphanumsort(tbl) --- @tparam table tbl the table to be sorted --- @treturn table the sorted table -function table.keysort(tbl) - local o = table.keys(tbl,true) - local _tbl = {} - for _,k in pairs(o) do _tbl[k] = tbl[k] end - return _tbl -end - -ExpLib:unpack_to_G() -return ExpLib \ No newline at end of file diff --git a/old/modules/ExpGamingLib/softmod.json b/old/modules/ExpGamingLib/softmod.json deleted file mode 100644 index 160803be..00000000 --- a/old/modules/ExpGamingLib/softmod.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "ExpGamingLib", - "version": "4.0.0", - "description": "Adds some common functions used though out all ExpGaming modules", - "location": "FSM_ARCHIVE", - "keywords": [ - "ExpGaming", - "Lib" - ], - "author": "Cooldude2606", - "contact": "Discord: Cooldude2606#5241", - "license": "https://github.com/explosivegaming/scenario/blob/master/LICENSE", - "dependencies": { - "FactorioStdLib.Game": "^0.8.0", - "FactorioStdLib.Color": "^0.8.0", - "FactorioStdLib.Table": "^0.8.0" - }, - "submodules": {} -} From 6f6a1732cec8b8d80470c1ad18a1523605e731d8 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 24 Mar 2019 16:58:20 +0000 Subject: [PATCH 07/18] Added format_time --- expcore/common.lua | 62 ++++++++++++++++++++++++++++++++ locale/en/expcore.cfg | 17 ++++++++- modules/addons/death-markers.lua | 37 +++++++++++++++++-- modules/commands/interface.lua | 1 + 4 files changed, 114 insertions(+), 3 deletions(-) diff --git a/expcore/common.lua b/expcore/common.lua index 1f7f6448..6cd27b56 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -135,4 +135,66 @@ function Public.ext_require(path,...) return Public.extract_keys(rtn,...) end +--- Formats ticks into a time format - this is alot of work and will do later +-- time denominations: D,H,M,S,T days,hours,minutes,seconds,ticks +-- time prefixes (minutes as example): %m,%m,%M,%MM just the value, value with short tag, value with long tag +-- adding a number after the prefix AND denomination will show that many decimal palaces +-- examples: '%H %M' => '0H 0M'; '%MM and %SS3' => '0 Minutes and 0.000 Seconds' +function Public.format_time(ticks,format) + local has_days, has_hours, has_minutes, has_seconds, has_ticks = false,false,false,false,false + local max_days, max_hours = ticks/5184000, ticks/216000 + local max_minutes, max_seconds, max_ticks = ticks/3600, ticks/60, ticks + local days, hours = max_days, max_hours-math.floor(max_days)*5184000 + local minutes, seconds = max_minutes-math.floor(max_hours)*216000, max_seconds-math.floor(max_minutes)*3600 + local tags = {} + return 'Use format_time_simple currently WIP' +end + +--- Formats tick into a time format, this format is predefined to either H:M:S; HH MM SS or H Hours M Minutes S seconds +-- seconds are not required to be shown with option show_seconds = false, true to show them, default false +-- show_sub_seconds will show three decimal places for the seconds +-- long_format will use words rather than letters +-- tagged is default to true when false it will remove all letters and use : +-- @tparam ticks number the number of ticks that represents a time +-- @tparam options table a table of options to use for the format +function Public.format_time_simple(ticks,options) + -- Sets up the options + options = { + show_seconds = options.show_seconds or false, + show_sub_seconds = options.show_sub_seconds or false, + long_format = options.long_format or false, + tagged = options.tagged or true + } + -- Basic numbers that are used in calculations + local max_hours, max_minutes, max_seconds = ticks/216000, ticks/3600, ticks/60 + local hours, minutes, seconds = max_hours, max_minutes-math.floor(max_hours)*216000, max_seconds-math.floor(max_minutes)*3600 + -- Format options + local suffix = 'time-format.short-' + if options.long_format then + suffix = 'time-format.long-' + end + local div = 'time-format.simple-format-tagged' + if options.tagged then + div = 'time-format.simple-format-div' + suffix = false + end + -- The returned numbers in the right format + local rtn_hours, rtn_minutes, rtn_seconds = math.floor(hours), math.floor(minutes), math.floor(seconds) + if suffix then + rtn_hours = {suffix..'hours',rtn_hours} + rtn_minutes = {suffix..'minutes',rtn_minutes} + if options.show_sub_seconds then + rtn_seconds = {suffix..'seconds',string.format('%d03',seconds)} + else + rtn_seconds = {suffix..'seconds',rtn_seconds} + end + end + -- The final return is construed + local rtn = {div,rtn_hours,rtn_minutes} + if options.show_seconds then + rtn = {div,rtn,rtn_seconds} + end + return rtn +end + return Public \ No newline at end of file diff --git a/locale/en/expcore.cfg b/locale/en/expcore.cfg index b33e7ee3..6dbc9b41 100644 --- a/locale/en/expcore.cfg +++ b/locale/en/expcore.cfg @@ -14,4 +14,19 @@ invalid-param=Invalid Param "__1__"; __2__ command-help=__1__ - __2__ command-ran=Command Complete command-fail=Command failed to run: __1__ -command-error-log-format=[ERROR] command/__1__ :: __2__ \ No newline at end of file +command-error-log-format=[ERROR] command/__1__ :: __2__ + +[time-format] +simple-format-none=__1__ +simple-format-div=__1__:__2__ +simple-format-tagged=__1__ __2__ +long-days=__1__ __plural_for_parameter_1_{1=Day|rest=Days}__ +short-days=__1__D +long-hours=__1__ __plural_for_parameter_1_{1=Hour|rest=Hours}__ +short-hours=__1__H +long-minutes=__1__ __plural_for_parameter_1_{1=Minute|rest=Minutes}__ +short-minutes=__1__M +long-seconds=__1__ __plural_for_parameter_1_{1=Second|rest=Seconds}__ +short-seconds=__1__S +long-ticks=__1__ __plural_for_parameter_1_{1=Tick|rest=Ticks}__ +short-ticks=__1__T \ No newline at end of file diff --git a/modules/addons/death-markers.lua b/modules/addons/death-markers.lua index 616854b9..c161dc5a 100644 --- a/modules/addons/death-markers.lua +++ b/modules/addons/death-markers.lua @@ -3,5 +3,38 @@ local Game = require 'utils.game' local Global = require 'utils.global' local Commands = require 'expcore.commands' local config = require 'config.death_markers' -local opt_require = ext_require('expcore.common','opt_require') -opt_require 'config.command_auth_runtime_disable' -- if the file is present then we can disable the commands \ No newline at end of file +local opt_require, format_time = ext_require('expcore.common','opt_require','format_time_simple') +opt_require 'config.command_auth_runtime_disable' -- if the file is present then we can disable the commands rather than not load them + +local bodies = { + --{player_name='Cooldude2606',time_of_death='15H 15M',body=LuaEntity,tag=LuaCustomChartTag} +} +Global.register(bodies,function(tbl) + bodies = tbl +end) + +--- Checks that all map tags are present and valid +-- adds missing ones, deletes expired ones +local function check_map_tags() + +end + +--- Teleports the owner of a body to the body +local function teleport_player(body) + +end + +--- Teleports the items in a body to a certain position putting it in chests +-- if there are no chests close by them some are created +local function teleport_items(body,position) + +end + +Event.add(defines.events.on_player_died,function(event) + +end) + +local check_period = 60*60*5 -- five minutes +Event.on_nth_tick(check_period,function(event) + +end) \ No newline at end of file diff --git a/modules/commands/interface.lua b/modules/commands/interface.lua index 24424ebf..da03fdd1 100644 --- a/modules/commands/interface.lua +++ b/modules/commands/interface.lua @@ -5,6 +5,7 @@ local Common = require 'expcore.common' -- modules that are loaded into the interface env to be accessed local interface_modules = { ['Game']='utils.game', + ['_C']=Common, ['Commands']=Commands, ['output']=Common.player_return, ['Group']='expcore.permission_groups' From 2f4f100b6306cb2ae1890e130eb370b3f0a5c9de Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 24 Mar 2019 17:37:33 +0000 Subject: [PATCH 08/18] Improved format_time --- expcore/common.lua | 101 +++++++++++++++++++++++------------------- locale/en/expcore.cfg | 12 +---- 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/expcore/common.lua b/expcore/common.lua index 6cd27b56..fbc9c158 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -135,64 +135,75 @@ function Public.ext_require(path,...) return Public.extract_keys(rtn,...) end ---- Formats ticks into a time format - this is alot of work and will do later --- time denominations: D,H,M,S,T days,hours,minutes,seconds,ticks --- time prefixes (minutes as example): %m,%m,%M,%MM just the value, value with short tag, value with long tag --- adding a number after the prefix AND denomination will show that many decimal palaces --- examples: '%H %M' => '0H 0M'; '%MM and %SS3' => '0 Minutes and 0.000 Seconds' -function Public.format_time(ticks,format) - local has_days, has_hours, has_minutes, has_seconds, has_ticks = false,false,false,false,false - local max_days, max_hours = ticks/5184000, ticks/216000 - local max_minutes, max_seconds, max_ticks = ticks/3600, ticks/60, ticks - local days, hours = max_days, max_hours-math.floor(max_days)*5184000 - local minutes, seconds = max_minutes-math.floor(max_hours)*216000, max_seconds-math.floor(max_minutes)*3600 - local tags = {} - return 'Use format_time_simple currently WIP' -end - ---- Formats tick into a time format, this format is predefined to either H:M:S; HH MM SS or H Hours M Minutes S seconds --- seconds are not required to be shown with option show_seconds = false, true to show them, default false --- show_sub_seconds will show three decimal places for the seconds --- long_format will use words rather than letters --- tagged is default to true when false it will remove all letters and use : +--- Formats tick into a clean format, denominations from highest to lowest +-- long will use words rather than letters +-- time will use : separates +-- when a denomination is false it will overflow into the next one -- @tparam ticks number the number of ticks that represents a time -- @tparam options table a table of options to use for the format -function Public.format_time_simple(ticks,options) +-- @treturn string a locale string that can be used +function Public.format_time(ticks,options) -- Sets up the options - options = { - show_seconds = options.show_seconds or false, - show_sub_seconds = options.show_sub_seconds or false, - long_format = options.long_format or false, - tagged = options.tagged or true + options = options or { + days=false, + hours=true, + minutes=true, + seconds=false, + long=false, + time=false } -- Basic numbers that are used in calculations - local max_hours, max_minutes, max_seconds = ticks/216000, ticks/3600, ticks/60 - local hours, minutes, seconds = max_hours, max_minutes-math.floor(max_hours)*216000, max_seconds-math.floor(max_minutes)*3600 + local max_days, max_hours, max_minutes, max_seconds = ticks/5184000, ticks/216000, ticks/3600, ticks/60 + local days, hours = max_days, max_hours-math.floor(max_days)*24 + local minutes, seconds = max_minutes-math.floor(max_hours)*60, max_seconds-math.floor(max_minutes)*60 + -- Handles overflow of disabled denominations + local rtn_days, rtn_hours, rtn_minutes, rtn_seconds = math.floor(days), math.floor(hours), math.floor(minutes), math.floor(seconds) + if not options.days then + rtn_hours = rtn_hours + rtn_days*24 + end + if not options.hours then + rtn_minutes = rtn_minutes + rtn_hours*60 + end + if not options.minutes then + rtn_seconds = rtn_seconds + rtn_minutes*60 + end -- Format options - local suffix = 'time-format.short-' - if options.long_format then - suffix = 'time-format.long-' + local suffix = 'time-symbol-' + local suffix_2 = '-short' + if options.long then + suffix = '' + suffix_2 = '' end local div = 'time-format.simple-format-tagged' - if options.tagged then + if options.time then div = 'time-format.simple-format-div' suffix = false end - -- The returned numbers in the right format - local rtn_hours, rtn_minutes, rtn_seconds = math.floor(hours), math.floor(minutes), math.floor(seconds) - if suffix then - rtn_hours = {suffix..'hours',rtn_hours} - rtn_minutes = {suffix..'minutes',rtn_minutes} - if options.show_sub_seconds then - rtn_seconds = {suffix..'seconds',string.format('%d03',seconds)} - else - rtn_seconds = {suffix..'seconds',rtn_seconds} - end + -- Adds formatting + if suffix ~= false then + rtn_days = {suffix..'days'..suffix_2,rtn_days} + rtn_hours = {suffix..'hours'..suffix_2,rtn_hours} + rtn_minutes = {suffix..'minutes'..suffix_2,rtn_minutes} + rtn_seconds = {suffix..'seconds'..suffix_2,rtn_seconds} + else + rtn_days = string.format('%02d',rtn_days) + rtn_hours = string.format('%02d',rtn_hours) + rtn_minutes = string.format('%02d',rtn_minutes) + rtn_seconds = string.format('%02d',rtn_seconds) end -- The final return is construed - local rtn = {div,rtn_hours,rtn_minutes} - if options.show_seconds then - rtn = {div,rtn,rtn_seconds} + local rtn + if options.days then + rtn = rtn_days + end + if options.hours then + rtn = rtn and {div,rtn,rtn_hours} or rtn_hours + end + if options.minutes then + rtn = rtn and {div,rtn,rtn_minutes} or rtn_minutes + end + if options.seconds then + rtn = rtn and {div,rtn,rtn_seconds} or rtn_seconds end return rtn end diff --git a/locale/en/expcore.cfg b/locale/en/expcore.cfg index 6dbc9b41..e5572501 100644 --- a/locale/en/expcore.cfg +++ b/locale/en/expcore.cfg @@ -1,3 +1,5 @@ +time-symbol-days-short=__1__d + [expcore-commands] unauthorized=Unauthorized, Access is denied due to invalid credentials reject-string-options=Invalid Option, Must be one of: __1__ @@ -20,13 +22,3 @@ command-error-log-format=[ERROR] command/__1__ :: __2__ simple-format-none=__1__ simple-format-div=__1__:__2__ simple-format-tagged=__1__ __2__ -long-days=__1__ __plural_for_parameter_1_{1=Day|rest=Days}__ -short-days=__1__D -long-hours=__1__ __plural_for_parameter_1_{1=Hour|rest=Hours}__ -short-hours=__1__H -long-minutes=__1__ __plural_for_parameter_1_{1=Minute|rest=Minutes}__ -short-minutes=__1__M -long-seconds=__1__ __plural_for_parameter_1_{1=Second|rest=Seconds}__ -short-seconds=__1__S -long-ticks=__1__ __plural_for_parameter_1_{1=Tick|rest=Ticks}__ -short-ticks=__1__T \ No newline at end of file From 498edfd58d3ad27e3ffd265fc9a6de2b8058108f Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 24 Mar 2019 18:47:43 +0000 Subject: [PATCH 09/18] Added Death logger --- .../{death_markers.lua => death_logger.lua} | 2 +- config/file_loader.lua | 1 + expcore/common.lua | 47 +++++++---- modules/addons/death-logger.lua | 84 +++++++++++++++++++ modules/addons/death-markers.lua | 40 --------- 5 files changed, 115 insertions(+), 59 deletions(-) rename config/{death_markers.lua => death_logger.lua} (90%) create mode 100644 modules/addons/death-logger.lua delete mode 100644 modules/addons/death-markers.lua diff --git a/config/death_markers.lua b/config/death_logger.lua similarity index 90% rename from config/death_markers.lua rename to config/death_logger.lua index cb195cde..f93518e0 100644 --- a/config/death_markers.lua +++ b/config/death_logger.lua @@ -8,5 +8,5 @@ return { auto_collect_bodies=false, -- enables items being returned to the spawn point in chests upon death show_map_markers=true, -- shows markers on the map where bodies are include_time_of_death=true, -- weather to include the time of death on the map marker - map_icon='' -- the icon that the map marker shows '' means no icon + map_icon=nil -- the icon that the map marker shows; nil means no icon; format as a SingleID } \ No newline at end of file diff --git a/config/file_loader.lua b/config/file_loader.lua index c87e9d85..db6b68bc 100644 --- a/config/file_loader.lua +++ b/config/file_loader.lua @@ -17,6 +17,7 @@ return { -- QoL Addons 'modules.addons.chat-popups', 'modules.addons.damage-popups', + 'modules.addons.death-markers', -- Config Files 'config.command_auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.command_auth_runtime_disable', -- allows commands to be enabled and disabled during runtime diff --git a/expcore/common.lua b/expcore/common.lua index fbc9c158..74f2eb3a 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -138,6 +138,7 @@ end --- Formats tick into a clean format, denominations from highest to lowest -- long will use words rather than letters -- time will use : separates +-- string will return a string not a locale string -- when a denomination is false it will overflow into the next one -- @tparam ticks number the number of ticks that represents a time -- @tparam options table a table of options to use for the format @@ -150,7 +151,8 @@ function Public.format_time(ticks,options) minutes=true, seconds=false, long=false, - time=false + time=false, + string=false } -- Basic numbers that are used in calculations local max_days, max_hours, max_minutes, max_seconds = ticks/5184000, ticks/216000, ticks/3600, ticks/60 @@ -174,18 +176,28 @@ function Public.format_time(ticks,options) suffix = '' suffix_2 = '' end - local div = 'time-format.simple-format-tagged' + local div = options.string and ' ' or 'time-format.simple-format-tagged' if options.time then - div = 'time-format.simple-format-div' + div = options.string and ':' or 'time-format.simple-format-div' suffix = false end -- Adds formatting if suffix ~= false then - rtn_days = {suffix..'days'..suffix_2,rtn_days} - rtn_hours = {suffix..'hours'..suffix_2,rtn_hours} - rtn_minutes = {suffix..'minutes'..suffix_2,rtn_minutes} - rtn_seconds = {suffix..'seconds'..suffix_2,rtn_seconds} + if options.string then + -- format it as a string + local long = suffix == '' + rtn_days = long and rtn_days..' days' or rtn_days..'d' + rtn_hours = long and rtn_hours..' hours' or rtn_hours..'h' + rtn_minutes = long and rtn_minutes..' minutes' or rtn_minutes..'m' + rtn_seconds = long and rtn_seconds..' seconds' or rtn_seconds..'s' + else + rtn_days = {suffix..'days'..suffix_2,rtn_days} + rtn_hours = {suffix..'hours'..suffix_2,rtn_hours} + rtn_minutes = {suffix..'minutes'..suffix_2,rtn_minutes} + rtn_seconds = {suffix..'seconds'..suffix_2,rtn_seconds} + end else + -- weather string or not it has same format rtn_days = string.format('%02d',rtn_days) rtn_hours = string.format('%02d',rtn_hours) rtn_minutes = string.format('%02d',rtn_minutes) @@ -193,18 +205,17 @@ function Public.format_time(ticks,options) end -- The final return is construed local rtn - if options.days then - rtn = rtn_days - end - if options.hours then - rtn = rtn and {div,rtn,rtn_hours} or rtn_hours - end - if options.minutes then - rtn = rtn and {div,rtn,rtn_minutes} or rtn_minutes - end - if options.seconds then - rtn = rtn and {div,rtn,rtn_seconds} or rtn_seconds + local append = function(dom,value) + if dom and options.string then + rtn = rtn and rtn..div..value or value + elseif dom then + rtn = rtn and {div,rtn,value} or value + end end + append(options.day,rtn_days) + append(options.hours,rtn_hours) + append(options.minutes,rtn_minutes) + append(options.seconds,rtn_seconds) return rtn end diff --git a/modules/addons/death-logger.lua b/modules/addons/death-logger.lua new file mode 100644 index 00000000..4743b99d --- /dev/null +++ b/modules/addons/death-logger.lua @@ -0,0 +1,84 @@ +local Event = require 'utils.event' +local Game = require 'utils.game' +local Global = require 'utils.global' +local config = require 'config.death_logger' +local format_time = ext_require('expcore.common','format_time') + +local deaths = { + archive={} -- deaths moved here after body is gone + --{player_name='Cooldude2606',time_of_death='15H 15M',position={x=0,y=0},corpse=LuaEntity,tag=LuaCustomChartTag} +} +Global.register(deaths,function(tbl) + deaths = tbl +end) + +--- Creates a new death marker and saves it to the given death +local function create_map_tag(death) + local player = Game.get_player_from_any(death.player_name) + local message = player.name..' died' + if config.include_time_of_death then + local time = format_time(death.time_of_death,{hours=true,minutes=true,string=true}) + message = message..' at '..time + end + death.tag = player.force.add_chart_tag(player.surface,{ + position=death.position, + icon=config.map_icon, + text=message + }) +end + +--- Checks that all map tags are present and valid +-- adds missing ones, deletes expired ones +local function check_map_tags() + for index,death in ipairs(deaths) do + local map_tag = death.tag + local corpse = death.corpse + -- Check the corpse is valid + if corpse and corpse.valid then + -- Corpse is valid check the map tag + if not map_tag or not map_tag.valid then + -- Map tag is not valid make a new one + create_map_tag(death) + end + else + -- Corpse is not valid so remove the map tag + if map_tag and map_tag.valid then + map_tag.destroy() + end + -- Move the death to the archive + death.corpse = nil + death.tag = nil + table.insert(deaths.archive,death) + table.remove(deaths,index) + end + end +end + +-- when a player dies a new death is added to the records and a map marker is made +Event.add(defines.events.on_player_died,function(event) + local player = Game.get_player_by_index(event.player_index) + local corpse = player.surface.find_entity('character-corpse',player.position) + local death = { + player_name = player.name, + time_of_death = event.tick, + position = player.position, + corpse = corpse + } + if config.show_map_markers then + create_map_tag(death) + end + table.insert(deaths,death) +end) + +-- every 5 min all bodies are checked for valid map tags +if config.show_map_markers then + local check_period = 60*60*5 -- five minutes + Event.on_nth_tick(check_period,function(event) + check_map_tags() + end) +end + +-- this is so other modules can access the logs +return function() + return deaths +end \ No newline at end of file diff --git a/modules/addons/death-markers.lua b/modules/addons/death-markers.lua deleted file mode 100644 index c161dc5a..00000000 --- a/modules/addons/death-markers.lua +++ /dev/null @@ -1,40 +0,0 @@ -local Event = require 'utils.event' -local Game = require 'utils.game' -local Global = require 'utils.global' -local Commands = require 'expcore.commands' -local config = require 'config.death_markers' -local opt_require, format_time = ext_require('expcore.common','opt_require','format_time_simple') -opt_require 'config.command_auth_runtime_disable' -- if the file is present then we can disable the commands rather than not load them - -local bodies = { - --{player_name='Cooldude2606',time_of_death='15H 15M',body=LuaEntity,tag=LuaCustomChartTag} -} -Global.register(bodies,function(tbl) - bodies = tbl -end) - ---- Checks that all map tags are present and valid --- adds missing ones, deletes expired ones -local function check_map_tags() - -end - ---- Teleports the owner of a body to the body -local function teleport_player(body) - -end - ---- Teleports the items in a body to a certain position putting it in chests --- if there are no chests close by them some are created -local function teleport_items(body,position) - -end - -Event.add(defines.events.on_player_died,function(event) - -end) - -local check_period = 60*60*5 -- five minutes -Event.on_nth_tick(check_period,function(event) - -end) \ No newline at end of file From 79ed80c60cd739107e87a0b09c149c3ceb0c3a44 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 24 Mar 2019 18:49:04 +0000 Subject: [PATCH 10/18] Commented out WIP config settings --- config/death_logger.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/death_logger.lua b/config/death_logger.lua index f93518e0..4b5ba5f5 100644 --- a/config/death_logger.lua +++ b/config/death_logger.lua @@ -2,10 +2,10 @@ -- allow_teleport_to_body_command and allow_collect_bodies_command can be over ridden if command_auth_runtime_disable is present -- if not present then the commands will not be loaded into the game return { - allow_teleport_to_body_command=false, -- allows use of /return-to-body which teleports you to your last death - allow_collect_bodies_command=false, -- allows use of /collect-body which returns all your items to you and removes the body - use_chests_as_bodies=false, -- weather items should be moved into a chest when a player dies - auto_collect_bodies=false, -- enables items being returned to the spawn point in chests upon death + --allow_teleport_to_body_command=false, -- allows use of /return-to-body which teleports you to your last death + --allow_collect_bodies_command=false, -- allows use of /collect-body which returns all your items to you and removes the body + --use_chests_as_bodies=false, -- weather items should be moved into a chest when a player dies + --auto_collect_bodies=false, -- enables items being returned to the spawn point in chests upon death show_map_markers=true, -- shows markers on the map where bodies are include_time_of_death=true, -- weather to include the time of death on the map marker map_icon=nil -- the icon that the map marker shows; nil means no icon; format as a SingleID From cfbab34c518333550652b9dd58e5a062af94256d Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Sun, 24 Mar 2019 20:06:43 +0000 Subject: [PATCH 11/18] Added Adv Starting Items --- config/advanced_starting_items.lua | 90 +++++++++++++++++++ config/file_loader.lua | 3 +- modules/addons/advanced-starting-items.lua | 34 +++++++ modules/factorio-control.lua | 8 ++ .../AdvancedStartingItems/control.lua | 0 .../AdvancedStartingItems/softmod.json | 0 6 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 config/advanced_starting_items.lua create mode 100644 modules/addons/advanced-starting-items.lua rename old/modules/{ => DONE}/AdvancedStartingItems/control.lua (100%) rename old/modules/{ => DONE}/AdvancedStartingItems/softmod.json (100%) diff --git a/config/advanced_starting_items.lua b/config/advanced_starting_items.lua new file mode 100644 index 00000000..0847ac6d --- /dev/null +++ b/config/advanced_starting_items.lua @@ -0,0 +1,90 @@ +--- This file is used to setup the map starting settings and the items players will start with + +--- These are called factories because they return another function +-- use these as a simple methods of adding new items +-- they will do most of the work for you +-- ['item-name']=factory(params) + +-- Use these to adjust for ticks ie game.tick < 5*minutes +local seconds, minutes, hours = 60, 3600, 216000 + +--- Use to make a split point for the number of items given based on time +-- ['stone-furnace']=cutoff_time(5*minutes,4,0) -- before 5 minutes give four items after 5 minutes give none +local function cutoff_time(time,before,after) + return function(amount_made,items_made,player) + if game.tick < time then return before + else return after + end + end +end + +--- Use to make a split point for the number of items given based on amount made +-- ['firearm-magazine']=cutoff_amount_made(100,10,0) -- give 10 items until 100 items have been made +local function cutoff_amount_made(amount,before,after) + return function(amount_made,items_made,player) + if amount_made < amount then return before + else return after + end + end +end + +--- Same as above but will not give any items if x amount has been made of another item, useful for tiers +-- ['light-armor']=cutoff_amount_made_unless(5,0,1,'heavy-armor',5) -- give light armor once 5 have been made unless 5 heavy armor has been made +local function cutoff_amount_made_unless(amount,before,after,second_item,second_amount) + return function(amount_made,items_made,player) + if items_made(second_item) < second_amount then + if amount_made < amount then return before + else return after + end + else return 0 + end + end +end + +-- Use for mass production items where you want the amount to change based on the amount already made +-- ['iron-plate']=scale_amount_made(5*minutes,10,10) -- for first 5 minutes give 10 items then after apply a factor of 10 +local function scale_amount_made(amount,before,scalar) + return function(amount_made,items_made,player) + if amount_made < amount then return before + else return (amount_made*scalar)/math.pow(game.tick/minutes,2) + end + end +end + +--[[ + Common values + game.tick is the amount of time the game has been on for + amount_made is the amount of that item which has been made + items_made('item-name') will return the amount of any item made + player is the player who just spawned + hours, minutes, seconds are the number of ticks in each unit of time +]] + +return { + skip_intro=true, -- skips the intro given in the default factorio free play scenario + friendly_fire=false, -- weather players will be able to attack each other on the same force + enemy_expansion=false, -- a catch all for in case the map settings file fails to load + chart_radius=10*32, -- the number of tiles that will be charted when the map starts + items = { -- items and there condition for being given + -- ['item-name'] = function(amount_made,production_stats,player) return end -- 0 means no items given + -- Plates + ['iron-plate']=scale_amount_made(100,10,10), + ['copper-plate']=scale_amount_made(100,0,8), + ['steel-plate']=scale_amount_made(100,0,4), + -- Secondary Items + ['electronic-circuit']=scale_amount_made(1000,0,6), + ['iron-gear-wheel']=scale_amount_made(1000,0,6), + -- Starting Items + ['burner-mining-drill']=cutoff_time(5*minutes,4,0), + ['stone-furnace']=cutoff_time(5*minutes,4,0), + -- Armor + ['light-armor']=cutoff_amount_made_unless(5,0,1,'heavy-armor',5), + ['heavy-armor']=cutoff_amount_made(5,0,1), + -- Weapon + ['pistol']=cutoff_amount_made_unless(0,1,1,'submachine-gun',5), + ['submachine-gun']=cutoff_amount_made(5,0,1), + -- Ammo + ['firearm-magazine']=cutoff_amount_made_unless(100,10,0,'piercing-rounds-magazine',100), + ['piercing-rounds-magazine']=cutoff_amount_made(100,0,10), + } +} \ No newline at end of file diff --git a/config/file_loader.lua b/config/file_loader.lua index db6b68bc..ee4cc877 100644 --- a/config/file_loader.lua +++ b/config/file_loader.lua @@ -17,7 +17,8 @@ return { -- QoL Addons 'modules.addons.chat-popups', 'modules.addons.damage-popups', - 'modules.addons.death-markers', + 'modules.addons.death-logger', + 'modules.addons.advanced-starting-items', -- Config Files 'config.command_auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.command_auth_runtime_disable', -- allows commands to be enabled and disabled during runtime diff --git a/modules/addons/advanced-starting-items.lua b/modules/addons/advanced-starting-items.lua new file mode 100644 index 00000000..f402e5dc --- /dev/null +++ b/modules/addons/advanced-starting-items.lua @@ -0,0 +1,34 @@ +--- Adds a better method of player starting items based on production levels. +local Event = require 'utils.event' +local Game = require 'utils.game' +local config = require 'config.advanced_starting_items' +local items = config.items + +Event.add(defines.events.on_player_created, function(event) + local player = Game.get_player_by_index(event.player_index) + -- game init settings + if event.player_index == 1 then + player.force.friendly_fire = config.friendly_fire + game.map_settings.enemy_expansion.enabled = config.enemy_expansion + local r = config.chart_radius + local p = player.position + player.force.chart(player.surface, {{p.x-r, p.y-r}, {p.x+r, p.y+r}}) + end + -- spawn items + for item,callback in pairs(items) do + if type(callback) == 'function' then + local stats = player.force.item_production_statistics + local made = stats.get_input_count(item) + local success,count = pcall(callback,made,stats.get_input_count,player) + if success and count > 0 then + player.insert{name=item,count=count} + end + end + end +end) + +Event.on_init(function() + remote.call('freeplay','set_created_items',{}) + remote.call('freeplay','set_chart_distance',0) + remote.call('freeplay','set_skip_intro',config.skip_intro) +end) \ No newline at end of file diff --git a/modules/factorio-control.lua b/modules/factorio-control.lua index 147dfb14..13557506 100644 --- a/modules/factorio-control.lua +++ b/modules/factorio-control.lua @@ -40,6 +40,14 @@ Event.add(defines.events.on_player_created, function(event) local r = global.chart_distance or 200 player.force.chart(player.surface, {{player.position.x - r, player.position.y - r}, {player.position.x + r, player.position.y + r}}) + if not global.skip_intro then + if game.is_multiplayer() then + player.print({"msg-intro"}) + else + game.show_message_dialog{text = {"msg-intro"}} + end + end + silo_script.on_event(event) end) diff --git a/old/modules/AdvancedStartingItems/control.lua b/old/modules/DONE/AdvancedStartingItems/control.lua similarity index 100% rename from old/modules/AdvancedStartingItems/control.lua rename to old/modules/DONE/AdvancedStartingItems/control.lua diff --git a/old/modules/AdvancedStartingItems/softmod.json b/old/modules/DONE/AdvancedStartingItems/softmod.json similarity index 100% rename from old/modules/AdvancedStartingItems/softmod.json rename to old/modules/DONE/AdvancedStartingItems/softmod.json From c49ac390acbc3066b2bba7d742e32b30a1f2fe30 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 25 Mar 2019 18:33:11 +0000 Subject: [PATCH 12/18] Added move_items to common --- expcore/common.lua | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/expcore/common.lua b/expcore/common.lua index 74f2eb3a..b3dbb28a 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -17,6 +17,7 @@ local Colours = require 'resources.color_presets' local Game = require 'utils.game' +local Util = require 'util' local Public = {} @@ -219,4 +220,51 @@ function Public.format_time(ticks,options) return rtn end +--- Moves items to the position and stores them in the closest entity of the type given +-- @tparam items table items which are to be added to the chests, {name='item-name',count=100} +-- @tparam[opt=navies] surface LuaSurface the surface that the items will be moved to +-- @tparam[opt={0,0}] position table the position that the items will be moved to {x=100,y=100} +-- @tparam[opt=32] radius number the radius in which the items are allowed to be placed +function Public.move_items(items,surface,position,radius,chest_type) + chest_type = chest_type or 'iron-chest' + surface = surface or game.surfaces[1] + if type(position) == 'table' then return end + if type(items) == 'table' then return end + -- Finds all entities of the given type + local p = position or {x=0,y=0} + local r = radius or 32 + local entities = surface.find_entities_filtered{area={{p.x-r,p.y-r},{p.x+r,p.y+r}},name=chest_type} or {} + local count = #entities + local current = 1 + -- Makes a new emtpy chest when it is needed + local function make_new_chest() + local pos = surface.find_non_colliding_position(chest_type,position,32,1) + local chest = surface.surface.create_entity{name=chest_type,position=pos} + table.insert(entities,chest) + count = count + 1 + return chest + end + -- Function used to round robin the items into all chests + local function next_chest(item) + local chest = entities[current] + if count == 0 then return make_new_chest() end + if chest.get_inventory(defines.inventory.chest).can_insert(item) then + -- If the item can be inserted then the chest is returned + current = current+1 + if current > count then current = 1 end + return chest + else + -- Other wise it is removed from the list + table.remove(entities,current) + count = count - 1 + end + end + -- Inserts the items into the chests + for _,item in pairs(items) do + local chest = next_chest(item) + if not chest then return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius',item.name,surface.name,p.x,p.y)) end + Util.insert_safe(chest,item) + end +end + return Public \ No newline at end of file From 03dfcb46a7eaebee1838d99aa5b5a49aafbaa553 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 25 Mar 2019 19:55:17 +0000 Subject: [PATCH 13/18] Added Spawn Base --- config/file_loader.lua | 1 + config/spawn_area.lua | 155 ++++++++++++++++++ modules/addons/spawn-area.lua | 140 ++++++++++++++++ old/modules/{ => DONE}/SpawnArea/control.lua | 0 old/modules/{ => DONE}/SpawnArea/softmod.json | 0 .../SpawnArea/src/spawn_entities.lua | 0 .../{ => DONE}/SpawnArea/src/spawn_tiles.lua | 0 7 files changed, 296 insertions(+) create mode 100644 config/spawn_area.lua create mode 100644 modules/addons/spawn-area.lua rename old/modules/{ => DONE}/SpawnArea/control.lua (100%) rename old/modules/{ => DONE}/SpawnArea/softmod.json (100%) rename old/modules/{ => DONE}/SpawnArea/src/spawn_entities.lua (100%) rename old/modules/{ => DONE}/SpawnArea/src/spawn_tiles.lua (100%) diff --git a/config/file_loader.lua b/config/file_loader.lua index ee4cc877..72802122 100644 --- a/config/file_loader.lua +++ b/config/file_loader.lua @@ -19,6 +19,7 @@ return { 'modules.addons.damage-popups', 'modules.addons.death-logger', 'modules.addons.advanced-starting-items', + 'modules.addons.spawn-area', -- Config Files 'config.command_auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.command_auth_runtime_disable', -- allows commands to be enabled and disabled during runtime diff --git a/config/spawn_area.lua b/config/spawn_area.lua new file mode 100644 index 00000000..4d8f8eaf --- /dev/null +++ b/config/spawn_area.lua @@ -0,0 +1,155 @@ +--- Used to config the spawn generation settings yes there is alot here i know just ignore the long tables at the end (they were generated with a command) +return { + infinite_ammo_turrets = { -- These turrets will have they ammo refilled automatically and can not be looted + enabled=true, -- weather the turrets will be created and refilled + ammo_type='uranium-rounds-magazine', -- the ammo type that will be used + locations={ -- locations of all turrets, this is default it can be changed during runtime + {surface=1,position={x=-3,y=-3}}, + {surface=1,position={x=3 ,y=-3}}, + {surface=1,position={x=-3,y=3 }}, + {surface=1,position={x=3 ,y=3 }} + } + }, + afk_belts = { + enabled=true, -- weather afk belts will be generated + locations={ -- top left connors of any afk belt loops to be added + {x=-5,y=-5}, + {x=5, y=-5}, + {x=-5,y=5 }, + {x=5, y=5 } + } + }, + corrections = { -- Some settings that have no where else to go + protect_entities=true, + offset = {x=0,y=-2}, -- a global offset value to correct the x and y values of the tables below + deconstruction_radius=20, -- when the spawn is made this area will have all entities removed first + deconstruction_tile='concrete', -- this is the tile that will spawn in the deconstruction radius + pattern_radius = 50, -- this is the radius of the pattern all water in this area will be filled + pattern_tile = 'stone-path' -- the tile that is used for the pattern + }, + entities = { -- All entities that will be created as part of spawn {entity-name,x-pos,y-pos} + {"stone-wall",-10,-6},{"stone-wall",-10,-5},{"stone-wall",-10,-4},{"stone-wall",-10,-3},{"stone-wall",-10,-2},{"stone-wall",-10,-1},{"stone-wall",-10,0},{"stone-wall",-10,3},{"stone-wall",-10,4},{"stone-wall",-10,5}, + {"stone-wall",-10,6},{"stone-wall",-10,7},{"stone-wall",-10,8},{"stone-wall",-10,9},{"stone-wall",-8,-8},{"small-lamp",-8,-4},{"small-lamp",-8,-1},{"iron-chest",-8,0},{"iron-chest",-8,3},{"small-lamp",-8,4}, + {"small-lamp",-8,7},{"stone-wall",-8,11},{"stone-wall",-7,-8},{"small-electric-pole",-7,-2},{"iron-chest",-7,0},{"iron-chest",-7,3},{"small-electric-pole",-7,5},{"stone-wall",-7,11},{"stone-wall",-6,-8},{"small-lamp",-6,-6}, + {"iron-chest",-6,0},{"iron-chest",-6,3},{"small-lamp",-6,9},{"stone-wall",-6,11},{"stone-wall",-5,-8},{"small-lamp",-5,-1},{"iron-chest",-5,0},{"iron-chest",-5,3},{"small-lamp",-5,4},{"stone-wall",-5,11}, + {"stone-wall",-4,-8},{"small-electric-pole",-4,-5},{"iron-chest",-4,0},{"iron-chest",-4,3},{"small-electric-pole",-4,8},{"stone-wall",-4,11},{"stone-wall",-3,-8},{"small-lamp",-3,-6},{"small-lamp",-3,-3},{"small-lamp",-3,6}, + {"small-lamp",-3,9},{"stone-wall",-3,11},{"stone-wall",-2,-8},{"iron-chest",-2,-6},{"iron-chest",-2,-5},{"iron-chest",-2,-4},{"iron-chest",-2,-3},{"iron-chest",-2,-2},{"iron-chest",-2,5},{"iron-chest",-2,6}, + {"iron-chest",-2,7},{"iron-chest",-2,8},{"iron-chest",-2,9},{"stone-wall",-2,11},{"stone-wall",1,-8},{"iron-chest",1,-6}, + {"iron-chest",1,-5},{"iron-chest",1,-4},{"iron-chest",1,-3},{"iron-chest",1,-2},{"iron-chest",1,5},{"iron-chest",1,6},{"iron-chest",1,7},{"iron-chest",1,8},{"iron-chest",1,9},{"stone-wall",1,11}, + {"stone-wall",2,-8},{"small-lamp",2,-6},{"small-lamp",2,-3},{"small-lamp",2,6},{"small-lamp",2,9},{"stone-wall",2,11},{"stone-wall",3,-8},{"small-electric-pole",3,-5},{"iron-chest",3,0},{"iron-chest",3,3}, + {"small-electric-pole",3,8},{"stone-wall",3,11},{"stone-wall",4,-8},{"small-lamp",4,-1},{"iron-chest",4,0},{"iron-chest",4,3},{"small-lamp",4,4},{"stone-wall",4,11},{"stone-wall",5,-8},{"small-lamp",5,-6}, + {"iron-chest",5,0},{"iron-chest",5,3},{"small-lamp",5,9},{"stone-wall",5,11},{"stone-wall",6,-8},{"small-electric-pole",6,-2},{"iron-chest",6,0},{"iron-chest",6,3},{"small-electric-pole",6,5},{"stone-wall",6,11}, + {"stone-wall",7,-8},{"small-lamp",7,-4},{"small-lamp",7,-1},{"iron-chest",7,0},{"iron-chest",7,3},{"small-lamp",7,4},{"small-lamp",7,7},{"stone-wall",7,11},{"stone-wall",9,-6},{"stone-wall",9,-5}, + {"stone-wall",9,-4},{"stone-wall",9,-3},{"stone-wall",9,-2},{"stone-wall",9,-1},{"stone-wall",9,0},{"stone-wall",9,3},{"stone-wall",9,4},{"stone-wall",9,5},{"stone-wall",9,6},{"stone-wall",9,7}, + {"stone-wall",9,8},{"stone-wall",9,9} + }, + tiles = { -- The location of the "pattern" tiles {x-pos,y-pos} + {-49,-3},{-49,-2},{-49,1},{-49,2},{-49,5},{-49,6},{-48,-4},{-48,-3},{-48,-2},{-48,1},{-48,2},{-48,5},{-48,6},{-48,7},{-47,-7},{-47,-6},{-47,-5},{-47,-4},{-47,-3},{-47,-2},{-47,5},{-47,6},{-47,7},{-47,8},{-47,9},{-47,10},{-46,-8},{-46,-7},{-46,-6},{-46,-5}, + {-46,-4},{-46,-3},{-46,-2},{-46,-1},{-46,4},{-46,5},{-46,6},{-46,7},{-46,8},{-46,9},{-46,10},{-46,11},{-45,-17},{-45,-16},{-45,-15},{-45,-14},{-45,-13},{-45,-12},{-45,-9},{-45,-8},{-45,-7},{-45,-2},{-45,-1},{-45,0},{-45,1},{-45,2},{-45,3},{-45,4},{-45,5},{-45,10}, + {-45,11},{-45,12},{-45,15},{-45,16},{-45,17},{-45,18},{-45,19},{-45,20},{-44,-18},{-44,-17},{-44,-16},{-44,-15},{-44,-14},{-44,-13},{-44,-12},{-44,-9},{-44,-8},{-44,-1},{-44,0},{-44,1},{-44,2},{-44,3},{-44,4},{-44,11},{-44,12},{-44,15},{-44,16},{-44,17},{-44,18},{-44,19}, + {-44,20},{-44,21},{-43,-19},{-43,-18},{-43,-17},{-43,-1},{-43,0},{-43,1},{-43,2},{-43,3},{-43,4},{-43,20},{-43,21},{-43,22},{-42,-19},{-42,-18},{-42,-1},{-42,0},{-42,1},{-42,2},{-42,3},{-42,4},{-42,21},{-42,22},{-41,-25},{-41,-24},{-41,-19},{-41,-18},{-41,-13},{-41,-12}, + {-41,-11},{-41,-10},{-41,-5},{-41,-4},{-41,7},{-41,8},{-41,13},{-41,14},{-41,15},{-41,16},{-41,21},{-41,22},{-41,27},{-41,28},{-40,-26},{-40,-25},{-40,-24},{-40,-20},{-40,-19},{-40,-18},{-40,-13},{-40,-12},{-40,-11},{-40,-10},{-40,-5},{-40,-4},{-40,7},{-40,8},{-40,13},{-40,14}, + {-40,15},{-40,16},{-40,21},{-40,22},{-40,23},{-40,27},{-40,28},{-40,29},{-39,-27},{-39,-26},{-39,-25},{-39,-24},{-39,-21},{-39,-20},{-39,-19},{-39,-13},{-39,-12},{-39,-5},{-39,-4},{-39,-3},{-39,-2},{-39,-1},{-39,0},{-39,1},{-39,2},{-39,3},{-39,4},{-39,5},{-39,6},{-39,7}, + {-39,8},{-39,15},{-39,16},{-39,22},{-39,23},{-39,24},{-39,27},{-39,28},{-39,29},{-39,30},{-38,-27},{-38,-26},{-38,-25},{-38,-24},{-38,-21},{-38,-20},{-38,-13},{-38,-12},{-38,-5},{-38,-4},{-38,-3},{-38,-2},{-38,-1},{-38,0},{-38,1},{-38,2},{-38,3},{-38,4},{-38,5},{-38,6}, + {-38,7},{-38,8},{-38,15},{-38,16},{-38,23},{-38,24},{-38,27},{-38,28},{-38,29},{-38,30},{-37,-17},{-37,-16},{-37,-13},{-37,-12},{-37,-11},{-37,-10},{-37,-4},{-37,-3},{-37,-2},{-37,-1},{-37,0},{-37,3},{-37,4},{-37,5},{-37,6},{-37,7},{-37,13},{-37,14},{-37,15},{-37,16}, + {-37,19},{-37,20},{-36,-17},{-36,-16},{-36,-13},{-36,-12},{-36,-11},{-36,-10},{-36,-9},{-36,-3},{-36,-2},{-36,-1},{-36,0},{-36,3},{-36,4},{-36,5},{-36,6},{-36,12},{-36,13},{-36,14},{-36,15},{-36,16},{-36,19},{-36,20},{-35,-29},{-35,-28},{-35,-23},{-35,-22},{-35,-17},{-35,-16}, + {-35,-12},{-35,-11},{-35,-10},{-35,-9},{-35,-8},{-35,11},{-35,12},{-35,13},{-35,14},{-35,15},{-35,19},{-35,20},{-35,25},{-35,26},{-35,31},{-35,32},{-34,-30},{-34,-29},{-34,-28},{-34,-23},{-34,-22},{-34,-17},{-34,-16},{-34,-15},{-34,-11},{-34,-10},{-34,-9},{-34,-8},{-34,11},{-34,12}, + {-34,13},{-34,14},{-34,18},{-34,19},{-34,20},{-34,25},{-34,26},{-34,31},{-34,32},{-34,33},{-33,-31},{-33,-30},{-33,-29},{-33,-28},{-33,-23},{-33,-22},{-33,-16},{-33,-15},{-33,-14},{-33,-5},{-33,-4},{-33,-1},{-33,0},{-33,3},{-33,4},{-33,7},{-33,8},{-33,17},{-33,18},{-33,19}, + {-33,25},{-33,26},{-33,31},{-33,32},{-33,33},{-33,34},{-32,-32},{-32,-31},{-32,-30},{-32,-29},{-32,-28},{-32,-27},{-32,-23},{-32,-22},{-32,-21},{-32,-15},{-32,-14},{-32,-6},{-32,-5},{-32,-4},{-32,-1},{-32,0},{-32,3},{-32,4},{-32,7},{-32,8},{-32,9},{-32,17},{-32,18},{-32,24}, + {-32,25},{-32,26},{-32,30},{-32,31},{-32,32},{-32,33},{-32,34},{-32,35},{-31,-33},{-31,-32},{-31,-31},{-31,-30},{-31,-29},{-31,-28},{-31,-27},{-31,-26},{-31,-22},{-31,-21},{-31,-20},{-31,-19},{-31,-18},{-31,-11},{-31,-10},{-31,-9},{-31,-8},{-31,-7},{-31,-6},{-31,-5},{-31,-1},{-31,0}, + {-31,1},{-31,2},{-31,3},{-31,4},{-31,8},{-31,9},{-31,10},{-31,11},{-31,12},{-31,13},{-31,14},{-31,21},{-31,22},{-31,23},{-31,24},{-31,25},{-31,29},{-31,30},{-31,31},{-31,32},{-31,33},{-31,34},{-31,35},{-31,36},{-30,-33},{-30,-32},{-30,-31},{-30,-30},{-30,-29},{-30,-28}, + {-30,-27},{-30,-26},{-30,-21},{-30,-20},{-30,-19},{-30,-18},{-30,-11},{-30,-10},{-30,-9},{-30,-8},{-30,-7},{-30,-6},{-30,-1},{-30,0},{-30,1},{-30,2},{-30,3},{-30,4},{-30,9},{-30,10},{-30,11},{-30,12},{-30,13},{-30,14},{-30,21},{-30,22},{-30,23},{-30,24},{-30,29},{-30,30}, + {-30,31},{-30,32},{-30,33},{-30,34},{-30,35},{-30,36},{-29,-37},{-29,-36},{-29,-30},{-29,-29},{-29,-28},{-29,-27},{-29,-26},{-29,-15},{-29,-14},{-29,-10},{-29,-9},{-29,-8},{-29,-7},{-29,10},{-29,11},{-29,12},{-29,13},{-29,17},{-29,18},{-29,29},{-29,30},{-29,31},{-29,32},{-29,33}, + {-29,39},{-29,40},{-28,-38},{-28,-37},{-28,-36},{-28,-29},{-28,-28},{-28,-27},{-28,-26},{-28,-16},{-28,-15},{-28,-14},{-28,-9},{-28,-8},{-28,11},{-28,12},{-28,17},{-28,18},{-28,19},{-28,29},{-28,30},{-28,31},{-28,32},{-28,39},{-28,40},{-28,41},{-27,-39},{-27,-38},{-27,-37},{-27,-36}, + {-27,-23},{-27,-22},{-27,-19},{-27,-18},{-27,-17},{-27,-16},{-27,-15},{-27,-5},{-27,-4},{-27,-1},{-27,0},{-27,1},{-27,2},{-27,3},{-27,4},{-27,7},{-27,8},{-27,18},{-27,19},{-27,20},{-27,21},{-27,22},{-27,25},{-27,26},{-27,39},{-27,40},{-27,41},{-27,42},{-26,-39},{-26,-38}, + {-26,-37},{-26,-36},{-26,-24},{-26,-23},{-26,-22},{-26,-19},{-26,-18},{-26,-17},{-26,-16},{-26,-6},{-26,-5},{-26,-4},{-26,-1},{-26,0},{-26,1},{-26,2},{-26,3},{-26,4},{-26,7},{-26,8},{-26,9},{-26,19},{-26,20},{-26,21},{-26,22},{-26,25},{-26,26},{-26,27},{-26,39},{-26,40}, + {-26,41},{-26,42},{-25,-33},{-25,-32},{-25,-31},{-25,-30},{-25,-25},{-25,-24},{-25,-23},{-25,-22},{-25,-19},{-25,-18},{-25,-17},{-25,-9},{-25,-8},{-25,-7},{-25,-6},{-25,-5},{-25,-4},{-25,-1},{-25,0},{-25,1},{-25,2},{-25,3},{-25,4},{-25,7},{-25,8},{-25,9},{-25,10},{-25,11}, + {-25,12},{-25,20},{-25,21},{-25,22},{-25,25},{-25,26},{-25,27},{-25,28},{-25,33},{-25,34},{-25,35},{-25,36},{-24,-33},{-24,-32},{-24,-31},{-24,-30},{-24,-29},{-24,-25},{-24,-24},{-24,-23},{-24,-22},{-24,-19},{-24,-18},{-24,-9},{-24,-8},{-24,-7},{-24,-6},{-24,-5},{-24,-4},{-24,-1}, + {-24,0},{-24,1},{-24,2},{-24,3},{-24,4},{-24,7},{-24,8},{-24,9},{-24,10},{-24,11},{-24,12},{-24,21},{-24,22},{-24,25},{-24,26},{-24,27},{-24,28},{-24,32},{-24,33},{-24,34},{-24,35},{-24,36},{-23,-37},{-23,-36},{-23,-30},{-23,-29},{-23,-28},{-23,-19},{-23,-18},{-23,-15}, + {-23,-14},{-23,-9},{-23,-8},{-23,-7},{-23,-6},{-23,-5},{-23,0},{-23,1},{-23,2},{-23,3},{-23,8},{-23,9},{-23,10},{-23,11},{-23,12},{-23,17},{-23,18},{-23,21},{-23,22},{-23,31},{-23,32},{-23,33},{-23,39},{-23,40},{-22,-38},{-22,-37},{-22,-36},{-22,-29},{-22,-28},{-22,-19}, + {-22,-18},{-22,-15},{-22,-14},{-22,-13},{-22,-9},{-22,-8},{-22,-7},{-22,-6},{-22,1},{-22,2},{-22,9},{-22,10},{-22,11},{-22,12},{-22,16},{-22,17},{-22,18},{-22,21},{-22,22},{-22,31},{-22,32},{-22,39},{-22,40},{-22,41},{-21,-41},{-21,-40},{-21,-39},{-21,-38},{-21,-37},{-21,-29}, + {-21,-28},{-21,-25},{-21,-24},{-21,-23},{-21,-22},{-21,-21},{-21,-20},{-21,-19},{-21,-18},{-21,-15},{-21,-14},{-21,-13},{-21,-12},{-21,-3},{-21,-2},{-21,5},{-21,6},{-21,15},{-21,16},{-21,17},{-21,18},{-21,21},{-21,22},{-21,23},{-21,24},{-21,25},{-21,26},{-21,27},{-21,28},{-21,31}, + {-21,32},{-21,40},{-21,41},{-21,42},{-21,43},{-21,44},{-20,-42},{-20,-41},{-20,-40},{-20,-39},{-20,-38},{-20,-29},{-20,-28},{-20,-25},{-20,-24},{-20,-23},{-20,-22},{-20,-21},{-20,-20},{-20,-19},{-20,-18},{-20,-15},{-20,-14},{-20,-13},{-20,-12},{-20,-3},{-20,-2},{-20,-1},{-20,4},{-20,5}, + {-20,6},{-20,15},{-20,16},{-20,17},{-20,18},{-20,21},{-20,22},{-20,23},{-20,24},{-20,25},{-20,26},{-20,27},{-20,28},{-20,31},{-20,32},{-20,41},{-20,42},{-20,43},{-20,44},{-20,45},{-19,-43},{-19,-42},{-19,-41},{-19,-35},{-19,-34},{-19,-33},{-19,-32},{-19,-25},{-19,-24},{-19,-23}, + {-19,-15},{-19,-14},{-19,-13},{-19,-9},{-19,-8},{-19,-7},{-19,-6},{-19,-2},{-19,-1},{-19,0},{-19,1},{-19,2},{-19,3},{-19,4},{-19,5},{-19,9},{-19,10},{-19,11},{-19,12},{-19,16},{-19,17},{-19,18},{-19,26},{-19,27},{-19,28},{-19,35},{-19,36},{-19,37},{-19,38},{-19,44}, + {-19,45},{-19,46},{-18,-43},{-18,-42},{-18,-35},{-18,-34},{-18,-33},{-18,-32},{-18,-31},{-18,-26},{-18,-25},{-18,-24},{-18,-15},{-18,-14},{-18,-10},{-18,-9},{-18,-8},{-18,-7},{-18,-6},{-18,-1},{-18,0},{-18,1},{-18,2},{-18,3},{-18,4},{-18,9},{-18,10},{-18,11},{-18,12},{-18,13}, + {-18,17},{-18,18},{-18,27},{-18,28},{-18,29},{-18,34},{-18,35},{-18,36},{-18,37},{-18,38},{-18,45},{-18,46},{-17,-43},{-17,-42},{-17,-32},{-17,-31},{-17,-30},{-17,-27},{-17,-26},{-17,-25},{-17,-21},{-17,-20},{-17,-19},{-17,-18},{-17,-17},{-17,-16},{-17,-15},{-17,-14},{-17,-11},{-17,-10}, + {-17,-9},{-17,-8},{-17,-7},{-17,-6},{-17,0},{-17,1},{-17,2},{-17,3},{-17,9},{-17,10},{-17,11},{-17,12},{-17,13},{-17,14},{-17,17},{-17,18},{-17,19},{-17,20},{-17,21},{-17,22},{-17,23},{-17,24},{-17,28},{-17,29},{-17,30},{-17,33},{-17,34},{-17,35},{-17,45},{-17,46}, + {-16,-43},{-16,-42},{-16,-31},{-16,-30},{-16,-27},{-16,-26},{-16,-21},{-16,-20},{-16,-19},{-16,-18},{-16,-17},{-16,-16},{-16,-15},{-16,-14},{-16,-11},{-16,-10},{-16,-9},{-16,-8},{-16,-7},{-16,-6},{-16,1},{-16,2},{-16,9},{-16,10},{-16,11},{-16,12},{-16,13},{-16,14},{-16,17},{-16,18}, + {-16,19},{-16,20},{-16,21},{-16,22},{-16,23},{-16,24},{-16,29},{-16,30},{-16,33},{-16,34},{-16,45},{-16,46},{-15,-43},{-15,-42},{-15,-39},{-15,-38},{-15,-37},{-15,-36},{-15,-35},{-15,-34},{-15,-20},{-15,-19},{-15,-18},{-15,-17},{-15,-10},{-15,-9},{-15,-8},{-15,-7},{-15,-3},{-15,-2}, + {-15,1},{-15,2},{-15,5},{-15,6},{-15,10},{-15,11},{-15,12},{-15,13},{-15,20},{-15,21},{-15,22},{-15,23},{-15,37},{-15,38},{-15,39},{-15,40},{-15,41},{-15,42},{-15,45},{-15,46},{-14,-43},{-14,-42},{-14,-39},{-14,-38},{-14,-37},{-14,-36},{-14,-35},{-14,-34},{-14,-33},{-14,-19}, + {-14,-18},{-14,-9},{-14,-8},{-14,-4},{-14,-3},{-14,-2},{-14,1},{-14,2},{-14,5},{-14,6},{-14,7},{-14,11},{-14,12},{-14,21},{-14,22},{-14,36},{-14,37},{-14,38},{-14,39},{-14,40},{-14,41},{-14,42},{-14,45},{-14,46},{-13,-39},{-13,-38},{-13,-35},{-13,-34},{-13,-33},{-13,-32}, + {-13,-29},{-13,-28},{-13,-15},{-13,-14},{-13,-5},{-13,-4},{-13,-3},{-13,-2},{-13,5},{-13,6},{-13,7},{-13,8},{-13,17},{-13,18},{-13,31},{-13,32},{-13,35},{-13,36},{-13,37},{-13,38},{-13,41},{-13,42},{-12,-39},{-12,-38},{-12,-35},{-12,-34},{-12,-33},{-12,-32},{-12,-29},{-12,-28}, + {-12,-27},{-12,-16},{-12,-15},{-12,-14},{-12,-13},{-12,-5},{-12,-4},{-12,-3},{-12,-2},{-12,5},{-12,6},{-12,7},{-12,8},{-12,16},{-12,17},{-12,18},{-12,19},{-12,30},{-12,31},{-12,32},{-12,35},{-12,36},{-12,37},{-12,38},{-12,41},{-12,42},{-11,-43},{-11,-42},{-11,-34},{-11,-33}, + {-11,-32},{-11,-29},{-11,-28},{-11,-27},{-11,-26},{-11,-23},{-11,-22},{-11,-21},{-11,-20},{-11,-17},{-11,-16},{-11,-15},{-11,-14},{-11,-13},{-11,-12},{-11,-9},{-11,-8},{-11,1},{-11,2},{-11,11},{-11,12},{-11,15},{-11,16},{-11,17},{-11,18},{-11,19},{-11,20},{-11,23},{-11,24},{-11,25}, + {-11,26},{-11,29},{-11,30},{-11,31},{-11,32},{-11,35},{-11,36},{-11,37},{-11,45},{-11,46},{-10,-44},{-10,-43},{-10,-42},{-10,-33},{-10,-32},{-10,-29},{-10,-28},{-10,-27},{-10,-26},{-10,-23},{-10,-22},{-10,-21},{-10,-20},{-10,-17},{-10,-16},{-10,-15},{-10,-14},{-10,-13},{-10,-12},{-10,-9}, + {-10,-8},{-10,-7},{-10,0},{-10,1},{-10,2},{-10,3},{-10,10},{-10,11},{-10,12},{-10,15},{-10,16},{-10,17},{-10,18},{-10,19},{-10,20},{-10,23},{-10,24},{-10,25},{-10,26},{-10,29},{-10,30},{-10,31},{-10,32},{-10,35},{-10,36},{-10,45},{-10,46},{-10,47},{-9,-45},{-9,-44}, + {-9,-43},{-9,-29},{-9,-28},{-9,-27},{-9,-23},{-9,-22},{-9,-21},{-9,-20},{-9,-17},{-9,-16},{-9,-15},{-9,-14},{-9,-13},{-9,-8},{-9,-7},{-9,-6},{-9,-5},{-9,-1},{-9,0},{-9,1},{-9,2},{-9,3},{-9,4},{-9,8},{-9,9},{-9,10},{-9,11},{-9,16},{-9,17},{-9,18}, + {-9,19},{-9,20},{-9,23},{-9,24},{-9,25},{-9,26},{-9,30},{-9,31},{-9,32},{-9,46},{-9,47},{-9,48},{-8,-45},{-8,-44},{-8,-30},{-8,-29},{-8,-28},{-8,-24},{-8,-23},{-8,-22},{-8,-21},{-8,-20},{-8,-17},{-8,-16},{-8,-15},{-8,-14},{-8,-7},{-8,-6},{-8,-5},{-8,-4}, + {-8,-1},{-8,0},{-8,1},{-8,2},{-8,3},{-8,4},{-8,7},{-8,8},{-8,9},{-8,10},{-8,17},{-8,18},{-8,19},{-8,20},{-8,23},{-8,24},{-8,25},{-8,26},{-8,27},{-8,31},{-8,32},{-8,33},{-8,47},{-8,48},{-7,-45},{-7,-44},{-7,-39},{-7,-38},{-7,-37},{-7,-36}, + {-7,-31},{-7,-30},{-7,-29},{-7,-25},{-7,-24},{-7,-23},{-7,-22},{-7,-21},{-7,-11},{-7,-10},{-7,-7},{-7,-6},{-7,-5},{-7,-4},{-7,7},{-7,8},{-7,9},{-7,10},{-7,13},{-7,14},{-7,24},{-7,25},{-7,26},{-7,27},{-7,28},{-7,32},{-7,33},{-7,34},{-7,39},{-7,40}, + {-7,41},{-7,42},{-7,47},{-7,48},{-6,-46},{-6,-45},{-6,-44},{-6,-39},{-6,-38},{-6,-37},{-6,-36},{-6,-35},{-6,-31},{-6,-30},{-6,-25},{-6,-24},{-6,-23},{-6,-22},{-6,-12},{-6,-11},{-6,-10},{-6,-6},{-6,-5},{-6,8},{-6,9},{-6,13},{-6,14},{-6,15},{-6,25},{-6,26}, + {-6,27},{-6,28},{-6,33},{-6,34},{-6,38},{-6,39},{-6,40},{-6,41},{-6,42},{-6,47},{-6,48},{-6,49},{-5,-47},{-5,-46},{-5,-45},{-5,-44},{-5,-37},{-5,-36},{-5,-35},{-5,-34},{-5,-19},{-5,-18},{-5,-13},{-5,-12},{-5,-11},{-5,-10},{-5,-1},{-5,0},{-5,1},{-5,2}, + {-5,3},{-5,4},{-5,13},{-5,14},{-5,15},{-5,16},{-5,21},{-5,22},{-5,37},{-5,38},{-5,39},{-5,40},{-5,47},{-5,48},{-5,49},{-5,50},{-4,-47},{-4,-46},{-4,-45},{-4,-44},{-4,-43},{-4,-37},{-4,-36},{-4,-35},{-4,-34},{-4,-19},{-4,-18},{-4,-17},{-4,-13},{-4,-12}, + {-4,-11},{-4,-10},{-4,-2},{-4,-1},{-4,0},{-4,1},{-4,2},{-4,3},{-4,4},{-4,5},{-4,13},{-4,14},{-4,15},{-4,16},{-4,20},{-4,21},{-4,22},{-4,37},{-4,38},{-4,39},{-4,40},{-4,46},{-4,47},{-4,48},{-4,49},{-4,50},{-3,-44},{-3,-43},{-3,-42},{-3,-41}, + {-3,-40},{-3,-37},{-3,-36},{-3,-35},{-3,-34},{-3,-31},{-3,-30},{-3,-29},{-3,-28},{-3,-25},{-3,-24},{-3,-23},{-3,-22},{-3,-18},{-3,-17},{-3,-16},{-3,-7},{-3,-6},{-3,-3},{-3,-2},{-3,-1},{-3,0},{-3,3},{-3,4},{-3,5},{-3,6},{-3,9},{-3,10},{-3,19},{-3,20}, + {-3,21},{-3,25},{-3,26},{-3,27},{-3,28},{-3,31},{-3,32},{-3,33},{-3,34},{-3,37},{-3,38},{-3,39},{-3,40},{-3,43},{-3,44},{-3,45},{-3,46},{-3,47},{-2,-43},{-2,-42},{-2,-41},{-2,-40},{-2,-37},{-2,-36},{-2,-35},{-2,-34},{-2,-31},{-2,-30},{-2,-29},{-2,-28}, + {-2,-25},{-2,-24},{-2,-23},{-2,-22},{-2,-21},{-2,-17},{-2,-16},{-2,-15},{-2,-8},{-2,-7},{-2,-6},{-2,-3},{-2,-2},{-2,-1},{-2,0},{-2,3},{-2,4},{-2,5},{-2,6},{-2,9},{-2,10},{-2,11},{-2,18},{-2,19},{-2,20},{-2,24},{-2,25},{-2,26},{-2,27},{-2,28}, + {-2,31},{-2,32},{-2,33},{-2,34},{-2,37},{-2,38},{-2,39},{-2,40},{-2,43},{-2,44},{-2,45},{-2,46},{-1,-47},{-1,-46},{-1,-43},{-1,-42},{-1,-41},{-1,-40},{-1,-37},{-1,-36},{-1,-29},{-1,-28},{-1,-25},{-1,-24},{-1,-23},{-1,-22},{-1,-21},{-1,-20},{-1,-17},{-1,-16}, + {-1,-15},{-1,-14},{-1,-13},{-1,-12},{-1,-9},{-1,-8},{-1,-7},{-1,-6},{-1,-3},{-1,-2},{-1,5},{-1,6},{-1,9},{-1,10},{-1,11},{-1,12},{-1,15},{-1,16},{-1,17},{-1,18},{-1,19},{-1,20},{-1,23},{-1,24},{-1,25},{-1,26},{-1,27},{-1,28},{-1,31},{-1,32}, + {-1,39},{-1,40},{-1,43},{-1,44},{-1,45},{-1,46},{-1,49},{-1,50},{0,-47},{0,-46},{0,-43},{0,-42},{0,-41},{0,-40},{0,-37},{0,-36},{0,-29},{0,-28},{0,-25},{0,-24},{0,-23},{0,-22},{0,-21},{0,-20},{0,-17},{0,-16},{0,-15},{0,-14},{0,-13},{0,-12}, + {0,-9},{0,-8},{0,-7},{0,-6},{0,-3},{0,-2},{0,5},{0,6},{0,9},{0,10},{0,11},{0,12},{0,15},{0,16},{0,17},{0,18},{0,19},{0,20},{0,23},{0,24},{0,25},{0,26},{0,27},{0,28},{0,31},{0,32},{0,39},{0,40},{0,43},{0,44}, + {0,45},{0,46},{0,49},{0,50},{1,-43},{1,-42},{1,-41},{1,-40},{1,-37},{1,-36},{1,-35},{1,-34},{1,-31},{1,-30},{1,-29},{1,-28},{1,-25},{1,-24},{1,-23},{1,-22},{1,-21},{1,-17},{1,-16},{1,-15},{1,-8},{1,-7},{1,-6},{1,-3},{1,-2},{1,-1}, + {1,0},{1,3},{1,4},{1,5},{1,6},{1,9},{1,10},{1,11},{1,18},{1,19},{1,20},{1,24},{1,25},{1,26},{1,27},{1,28},{1,31},{1,32},{1,33},{1,34},{1,37},{1,38},{1,39},{1,40},{1,43},{1,44},{1,45},{1,46},{2,-44},{2,-43}, + {2,-42},{2,-41},{2,-40},{2,-37},{2,-36},{2,-35},{2,-34},{2,-31},{2,-30},{2,-29},{2,-28},{2,-25},{2,-24},{2,-23},{2,-22},{2,-18},{2,-17},{2,-16},{2,-7},{2,-6},{2,-3},{2,-2},{2,-1},{2,0},{2,3},{2,4},{2,5},{2,6},{2,9},{2,10}, + {2,19},{2,20},{2,21},{2,25},{2,26},{2,27},{2,28},{2,31},{2,32},{2,33},{2,34},{2,37},{2,38},{2,39},{2,40},{2,43},{2,44},{2,45},{2,46},{2,47},{3,-47},{3,-46},{3,-45},{3,-44},{3,-43},{3,-37},{3,-36},{3,-35},{3,-34},{3,-19}, + {3,-18},{3,-17},{3,-13},{3,-12},{3,-11},{3,-10},{3,-2},{3,-1},{3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,13},{3,14},{3,15},{3,16},{3,20},{3,21},{3,22},{3,37},{3,38},{3,39},{3,40},{3,46},{3,47},{3,48},{3,49},{3,50}, + {4,-47},{4,-46},{4,-45},{4,-44},{4,-37},{4,-36},{4,-35},{4,-34},{4,-19},{4,-18},{4,-13},{4,-12},{4,-11},{4,-10},{4,-1},{4,0},{4,1},{4,2},{4,3},{4,4},{4,13},{4,14},{4,15},{4,16},{4,21},{4,22},{4,37},{4,38},{4,39},{4,40}, + {4,47},{4,48},{4,49},{4,50},{5,-46},{5,-45},{5,-44},{5,-39},{5,-38},{5,-37},{5,-36},{5,-35},{5,-31},{5,-30},{5,-25},{5,-24},{5,-23},{5,-22},{5,-12},{5,-11},{5,-10},{5,-6},{5,-5},{5,8},{5,9},{5,13},{5,14},{5,15},{5,25},{5,26}, + {5,27},{5,28},{5,33},{5,34},{5,38},{5,39},{5,40},{5,41},{5,42},{5,47},{5,48},{5,49},{6,-45},{6,-44},{6,-39},{6,-38},{6,-37},{6,-36},{6,-31},{6,-30},{6,-29},{6,-25},{6,-24},{6,-23},{6,-22},{6,-21},{6,-11},{6,-10},{6,-7},{6,-6}, + {6,-5},{6,-4},{6,7},{6,8},{6,9},{6,10},{6,13},{6,14},{6,24},{6,25},{6,26},{6,27},{6,28},{6,32},{6,33},{6,34},{6,39},{6,40},{6,41},{6,42},{6,47},{6,48},{7,-45},{7,-44},{7,-30},{7,-29},{7,-28},{7,-24},{7,-23},{7,-22}, + {7,-21},{7,-20},{7,-17},{7,-16},{7,-15},{7,-14},{7,-7},{7,-6},{7,-5},{7,-4},{7,-1},{7,0},{7,1},{7,2},{7,3},{7,4},{7,7},{7,8},{7,9},{7,10},{7,17},{7,18},{7,19},{7,20},{7,23},{7,24},{7,25},{7,26},{7,27},{7,31}, + {7,32},{7,33},{7,47},{7,48},{8,-45},{8,-44},{8,-43},{8,-29},{8,-28},{8,-27},{8,-23},{8,-22},{8,-21},{8,-20},{8,-17},{8,-16},{8,-15},{8,-14},{8,-13},{8,-8},{8,-7},{8,-6},{8,-5},{8,-1},{8,0},{8,1},{8,2},{8,3},{8,4},{8,8}, + {8,9},{8,10},{8,11},{8,16},{8,17},{8,18},{8,19},{8,20},{8,23},{8,24},{8,25},{8,26},{8,30},{8,31},{8,32},{8,46},{8,47},{8,48},{9,-44},{9,-43},{9,-42},{9,-33},{9,-32},{9,-29},{9,-28},{9,-27},{9,-26},{9,-23},{9,-22},{9,-21}, + {9,-20},{9,-17},{9,-16},{9,-15},{9,-14},{9,-13},{9,-12},{9,-9},{9,-8},{9,-7},{9,0},{9,1},{9,2},{9,3},{9,10},{9,11},{9,12},{9,15},{9,16},{9,17},{9,18},{9,19},{9,20},{9,23},{9,24},{9,25},{9,26},{9,29},{9,30},{9,31}, + {9,32},{9,35},{9,36},{9,45},{9,46},{9,47},{10,-43},{10,-42},{10,-34},{10,-33},{10,-32},{10,-29},{10,-28},{10,-27},{10,-26},{10,-23},{10,-22},{10,-21},{10,-20},{10,-17},{10,-16},{10,-15},{10,-14},{10,-13},{10,-12},{10,-9},{10,-8},{10,1},{10,2},{10,11}, + {10,12},{10,15},{10,16},{10,17},{10,18},{10,19},{10,20},{10,23},{10,24},{10,25},{10,26},{10,29},{10,30},{10,31},{10,32},{10,35},{10,36},{10,37},{10,45},{10,46},{11,-39},{11,-38},{11,-35},{11,-34},{11,-33},{11,-32},{11,-29},{11,-28},{11,-27},{11,-16}, + {11,-15},{11,-14},{11,-13},{11,-5},{11,-4},{11,-3},{11,-2},{11,5},{11,6},{11,7},{11,8},{11,16},{11,17},{11,18},{11,19},{11,30},{11,31},{11,32},{11,35},{11,36},{11,37},{11,38},{11,41},{11,42},{12,-39},{12,-38},{12,-35},{12,-34},{12,-33},{12,-32}, + {12,-29},{12,-28},{12,-15},{12,-14},{12,-5},{12,-4},{12,-3},{12,-2},{12,5},{12,6},{12,7},{12,8},{12,17},{12,18},{12,31},{12,32},{12,35},{12,36},{12,37},{12,38},{12,41},{12,42},{13,-43},{13,-42},{13,-39},{13,-38},{13,-37},{13,-36},{13,-35},{13,-34}, + {13,-33},{13,-19},{13,-18},{13,-9},{13,-8},{13,-4},{13,-3},{13,-2},{13,1},{13,2},{13,5},{13,6},{13,7},{13,11},{13,12},{13,21},{13,22},{13,36},{13,37},{13,38},{13,39},{13,40},{13,41},{13,42},{13,45},{13,46},{14,-43},{14,-42},{14,-39},{14,-38}, + {14,-37},{14,-36},{14,-35},{14,-34},{14,-20},{14,-19},{14,-18},{14,-17},{14,-10},{14,-9},{14,-8},{14,-7},{14,-3},{14,-2},{14,1},{14,2},{14,5},{14,6},{14,10},{14,11},{14,12},{14,13},{14,20},{14,21},{14,22},{14,23},{14,37},{14,38},{14,39},{14,40}, + {14,41},{14,42},{14,45},{14,46},{15,-43},{15,-42},{15,-31},{15,-30},{15,-27},{15,-26},{15,-21},{15,-20},{15,-19},{15,-18},{15,-17},{15,-16},{15,-15},{15,-14},{15,-11},{15,-10},{15,-9},{15,-8},{15,-7},{15,-6},{15,1},{15,2},{15,9},{15,10},{15,11},{15,12}, + {15,13},{15,14},{15,17},{15,18},{15,19},{15,20},{15,21},{15,22},{15,23},{15,24},{15,29},{15,30},{15,33},{15,34},{15,45},{15,46},{16,-43},{16,-42},{16,-32},{16,-31},{16,-30},{16,-27},{16,-26},{16,-25},{16,-21},{16,-20},{16,-19},{16,-18},{16,-17},{16,-16}, + {16,-15},{16,-14},{16,-11},{16,-10},{16,-9},{16,-8},{16,-7},{16,-6},{16,0},{16,1},{16,2},{16,3},{16,9},{16,10},{16,11},{16,12},{16,13},{16,14},{16,17},{16,18},{16,19},{16,20},{16,21},{16,22},{16,23},{16,24},{16,28},{16,29},{16,30},{16,33}, + {16,34},{16,35},{16,45},{16,46},{17,-43},{17,-42},{17,-35},{17,-34},{17,-33},{17,-32},{17,-31},{17,-26},{17,-25},{17,-24},{17,-15},{17,-14},{17,-10},{17,-9},{17,-8},{17,-7},{17,-6},{17,-1},{17,0},{17,1},{17,2},{17,3},{17,4},{17,9},{17,10},{17,11}, + {17,12},{17,13},{17,17},{17,18},{17,27},{17,28},{17,29},{17,34},{17,35},{17,36},{17,37},{17,38},{17,45},{17,46},{18,-43},{18,-42},{18,-41},{18,-35},{18,-34},{18,-33},{18,-32},{18,-25},{18,-24},{18,-23},{18,-15},{18,-14},{18,-13},{18,-9},{18,-8},{18,-7}, + {18,-6},{18,-2},{18,-1},{18,0},{18,1},{18,2},{18,3},{18,4},{18,5},{18,9},{18,10},{18,11},{18,12},{18,16},{18,17},{18,18},{18,26},{18,27},{18,28},{18,35},{18,36},{18,37},{18,38},{18,44},{18,45},{18,46},{19,-42},{19,-41},{19,-40},{19,-39}, + {19,-38},{19,-29},{19,-28},{19,-25},{19,-24},{19,-23},{19,-22},{19,-21},{19,-20},{19,-19},{19,-18},{19,-15},{19,-14},{19,-13},{19,-12},{19,-3},{19,-2},{19,-1},{19,4},{19,5},{19,6},{19,15},{19,16},{19,17},{19,18},{19,21},{19,22},{19,23},{19,24},{19,25}, + {19,26},{19,27},{19,28},{19,31},{19,32},{19,41},{19,42},{19,43},{19,44},{19,45},{20,-41},{20,-40},{20,-39},{20,-38},{20,-37},{20,-29},{20,-28},{20,-25},{20,-24},{20,-23},{20,-22},{20,-21},{20,-20},{20,-19},{20,-18},{20,-15},{20,-14},{20,-13},{20,-12},{20,-3}, + {20,-2},{20,5},{20,6},{20,15},{20,16},{20,17},{20,18},{20,21},{20,22},{20,23},{20,24},{20,25},{20,26},{20,27},{20,28},{20,31},{20,32},{20,40},{20,41},{20,42},{20,43},{20,44},{21,-38},{21,-37},{21,-36},{21,-29},{21,-28},{21,-19},{21,-18},{21,-15}, + {21,-14},{21,-13},{21,-9},{21,-8},{21,-7},{21,-6},{21,1},{21,2},{21,9},{21,10},{21,11},{21,12},{21,16},{21,17},{21,18},{21,21},{21,22},{21,31},{21,32},{21,39},{21,40},{21,41},{22,-37},{22,-36},{22,-30},{22,-29},{22,-28},{22,-19},{22,-18},{22,-15}, + {22,-14},{22,-9},{22,-8},{22,-7},{22,-6},{22,-5},{22,0},{22,1},{22,2},{22,3},{22,8},{22,9},{22,10},{22,11},{22,12},{22,17},{22,18},{22,21},{22,22},{22,31},{22,32},{22,33},{22,39},{22,40},{23,-33},{23,-32},{23,-31},{23,-30},{23,-29},{23,-25}, + {23,-24},{23,-23},{23,-22},{23,-19},{23,-18},{23,-9},{23,-8},{23,-7},{23,-6},{23,-5},{23,-4},{23,-1},{23,0},{23,1},{23,2},{23,3},{23,4},{23,7},{23,8},{23,9},{23,10},{23,11},{23,12},{23,21},{23,22},{23,25},{23,26},{23,27},{23,28},{23,32}, + {23,33},{23,34},{23,35},{23,36},{24,-33},{24,-32},{24,-31},{24,-30},{24,-25},{24,-24},{24,-23},{24,-22},{24,-19},{24,-18},{24,-17},{24,-9},{24,-8},{24,-7},{24,-6},{24,-5},{24,-4},{24,-1},{24,0},{24,1},{24,2},{24,3},{24,4},{24,7},{24,8},{24,9}, + {24,10},{24,11},{24,12},{24,20},{24,21},{24,22},{24,25},{24,26},{24,27},{24,28},{24,33},{24,34},{24,35},{24,36},{25,-39},{25,-38},{25,-37},{25,-36},{25,-24},{25,-23},{25,-22},{25,-19},{25,-18},{25,-17},{25,-16},{25,-6},{25,-5},{25,-4},{25,-1},{25,0}, + {25,1},{25,2},{25,3},{25,4},{25,7},{25,8},{25,9},{25,19},{25,20},{25,21},{25,22},{25,25},{25,26},{25,27},{25,39},{25,40},{25,41},{25,42},{26,-39},{26,-38},{26,-37},{26,-36},{26,-23},{26,-22},{26,-19},{26,-18},{26,-17},{26,-16},{26,-15},{26,-5}, + {26,-4},{26,-1},{26,0},{26,1},{26,2},{26,3},{26,4},{26,7},{26,8},{26,18},{26,19},{26,20},{26,21},{26,22},{26,25},{26,26},{26,39},{26,40},{26,41},{26,42},{27,-38},{27,-37},{27,-36},{27,-29},{27,-28},{27,-27},{27,-26},{27,-16},{27,-15},{27,-14}, + {27,-9},{27,-8},{27,11},{27,12},{27,17},{27,18},{27,19},{27,29},{27,30},{27,31},{27,32},{27,39},{27,40},{27,41},{28,-37},{28,-36},{28,-30},{28,-29},{28,-28},{28,-27},{28,-26},{28,-15},{28,-14},{28,-10},{28,-9},{28,-8},{28,-7},{28,10},{28,11},{28,12}, + {28,13},{28,17},{28,18},{28,29},{28,30},{28,31},{28,32},{28,33},{28,39},{28,40},{29,-33},{29,-32},{29,-31},{29,-30},{29,-29},{29,-28},{29,-27},{29,-26},{29,-21},{29,-20},{29,-19},{29,-18},{29,-11},{29,-10},{29,-9},{29,-8},{29,-7},{29,-6},{29,-1},{29,0}, + {29,1},{29,2},{29,3},{29,4},{29,9},{29,10},{29,11},{29,12},{29,13},{29,14},{29,21},{29,22},{29,23},{29,24},{29,29},{29,30},{29,31},{29,32},{29,33},{29,34},{29,35},{29,36},{30,-33},{30,-32},{30,-31},{30,-30},{30,-29},{30,-28},{30,-27},{30,-26}, + {30,-22},{30,-21},{30,-20},{30,-19},{30,-18},{30,-11},{30,-10},{30,-9},{30,-8},{30,-7},{30,-6},{30,-5},{30,-1},{30,0},{30,1},{30,2},{30,3},{30,4},{30,8},{30,9},{30,10},{30,11},{30,12},{30,13},{30,14},{30,21},{30,22},{30,23},{30,24},{30,25}, + {30,29},{30,30},{30,31},{30,32},{30,33},{30,34},{30,35},{30,36},{31,-32},{31,-31},{31,-30},{31,-29},{31,-28},{31,-27},{31,-23},{31,-22},{31,-21},{31,-15},{31,-14},{31,-6},{31,-5},{31,-4},{31,-1},{31,0},{31,3},{31,4},{31,7},{31,8},{31,9},{31,17}, + {31,18},{31,24},{31,25},{31,26},{31,30},{31,31},{31,32},{31,33},{31,34},{31,35},{32,-31},{32,-30},{32,-29},{32,-28},{32,-23},{32,-22},{32,-16},{32,-15},{32,-14},{32,-5},{32,-4},{32,-1},{32,0},{32,3},{32,4},{32,7},{32,8},{32,17},{32,18},{32,19}, + {32,25},{32,26},{32,31},{32,32},{32,33},{32,34},{33,-30},{33,-29},{33,-28},{33,-23},{33,-22},{33,-17},{33,-16},{33,-15},{33,-11},{33,-10},{33,-9},{33,-8},{33,11},{33,12},{33,13},{33,14},{33,18},{33,19},{33,20},{33,25},{33,26},{33,31},{33,32},{33,33}, + {34,-29},{34,-28},{34,-23},{34,-22},{34,-17},{34,-16},{34,-12},{34,-11},{34,-10},{34,-9},{34,-8},{34,11},{34,12},{34,13},{34,14},{34,15},{34,19},{34,20},{34,25},{34,26},{34,31},{34,32},{35,-17},{35,-16},{35,-13},{35,-12},{35,-11},{35,-10},{35,-9},{35,-3}, + {35,-2},{35,-1},{35,0},{35,3},{35,4},{35,5},{35,6},{35,12},{35,13},{35,14},{35,15},{35,16},{35,19},{35,20},{36,-17},{36,-16},{36,-13},{36,-12},{36,-11},{36,-10},{36,-4},{36,-3},{36,-2},{36,-1},{36,0},{36,3},{36,4},{36,5},{36,6},{36,7}, + {36,13},{36,14},{36,15},{36,16},{36,19},{36,20},{37,-27},{37,-26},{37,-25},{37,-24},{37,-21},{37,-20},{37,-13},{37,-12},{37,-5},{37,-4},{37,-3},{37,-2},{37,-1},{37,0},{37,1},{37,2},{37,3},{37,4},{37,5},{37,6},{37,7},{37,8},{37,15},{37,16}, + {37,23},{37,24},{37,27},{37,28},{37,29},{37,30},{38,-27},{38,-26},{38,-25},{38,-24},{38,-21},{38,-20},{38,-19},{38,-13},{38,-12},{38,-5},{38,-4},{38,-3},{38,-2},{38,-1},{38,0},{38,1},{38,2},{38,3},{38,4},{38,5},{38,6},{38,7},{38,8},{38,15}, + {38,16},{38,22},{38,23},{38,24},{38,27},{38,28},{38,29},{38,30},{39,-26},{39,-25},{39,-24},{39,-20},{39,-19},{39,-18},{39,-13},{39,-12},{39,-11},{39,-10},{39,-5},{39,-4},{39,7},{39,8},{39,13},{39,14},{39,15},{39,16},{39,21},{39,22},{39,23},{39,27}, + {39,28},{39,29},{40,-25},{40,-24},{40,-19},{40,-18},{40,-13},{40,-12},{40,-11},{40,-10},{40,-5},{40,-4},{40,7},{40,8},{40,13},{40,14},{40,15},{40,16},{40,21},{40,22},{40,27},{40,28},{41,-19},{41,-18},{41,-1},{41,0},{41,1},{41,2},{41,3},{41,4}, + {41,21},{41,22},{42,-19},{42,-18},{42,-17},{42,-1},{42,0},{42,1},{42,2},{42,3},{42,4},{42,20},{42,21},{42,22},{43,-18},{43,-17},{43,-16},{43,-15},{43,-14},{43,-13},{43,-12},{43,-9},{43,-8},{43,-1},{43,0},{43,1},{43,2},{43,3},{43,4},{43,11}, + {43,12},{43,15},{43,16},{43,17},{43,18},{43,19},{43,20},{43,21},{44,-17},{44,-16},{44,-15},{44,-14},{44,-13},{44,-12},{44,-9},{44,-8},{44,-7},{44,-2},{44,-1},{44,0},{44,1},{44,2},{44,3},{44,4},{44,5},{44,10},{44,11},{44,12},{44,15},{44,16}, + {44,17},{44,18},{44,19},{44,20},{45,-8},{45,-7},{45,-6},{45,-5},{45,-4},{45,-3},{45,-2},{45,-1},{45,4},{45,5},{45,6},{45,7},{45,8},{45,9},{45,10},{45,11},{46,-7},{46,-6},{46,-5},{46,-4},{46,-3},{46,-2},{46,5},{46,6},{46,7},{46,8}, + {46,9},{46,10},{47,-4},{47,-3},{47,-2},{47,1},{47,2},{47,5},{47,6},{47,7},{48,-3},{48,-2},{48,1},{48,2},{48,5},{48,6} + } +} \ No newline at end of file diff --git a/modules/addons/spawn-area.lua b/modules/addons/spawn-area.lua new file mode 100644 index 00000000..9483fac8 --- /dev/null +++ b/modules/addons/spawn-area.lua @@ -0,0 +1,140 @@ +local Global = require 'utils.global' +local Event = require 'utils.event' +local Game = require 'utils.game' +local config = require 'config.spawn_area' +local tiles = config.tiles +local entities = config.entities +local belts = config.afk_belts.locations +local turrets = config.infinite_ammo_turrets.locations + +Global.register(turrets,function(tbl) + turrets = tbl +end) + +-- returns the Spawn force or creates it +local function get_spawn_force() + local force = game.forces['Spawn'] + if force and force.valid then return force end + force = game.create_force('Spawn') + force.set_cease_fire('player',true) + game.forces['player'].set_cease_fire('Spawn',true) + return force +end + +-- protects and entity so players cant do anything to it +local function protect_entity(entity,set_force) + if entity and entity.valid then + entity.destructible = false + entity.minable = false + entity.rotatable = false + entity.operable = false + if not set_force then entity.health = 0 end + if set_force then entity.force = get_spawn_force() end + end +end + +-- handles the infinite ammo turrets +local function spawn_turrets() + if config.infinite_ammo_turrets.enabled then + for _,turret_pos in pairs(turrets) do + local surface = game.surfaces[turret_pos.surface] + local p = turret_pos.position + local turret = surface.find_entity('gun-turret',p) + -- Makes a new turret if it is not found + if not turret or not turret.valid then + turret = surface.create_entity{name='gun-turret',position=p,force='Spawn'} + protect_entity(turret,true) + end + -- adds ammo to the turret + local inv = turret.get_inventory(defines.inventory.turret_ammo) + if inv.can_insert{name=config.infinite_ammo_turrets.ammo_type,count=10} then + inv.insert{name=config.infinite_ammo_turrets.ammo_type,count=10} + end + end + end +end + +-- makes a 2x2 afk belt where set in config +local function spawn_belts(surface) + local belt_details = {{-0.5,-0.5,2},{0.5,-0.5,4},{-0.5,0.5,0},{0.5,0.5,6}} -- x,y,dir + for _,belt_set in pairs(belts) do + local o = belt_set + for _,belt in pairs(belt_details) do + local p = {x=o.x+belt[1],y=o.y+belt[2]} + local belt_entity = surface.create_entity{name='transport-belt',position=p,force='neutral',direction=belt[3]} + protect_entity(belt_entity) + end + end +end + +-- generates an area with no water and removes entities in the decon area +local function spawn_base(surface,position) + local dr = config.corrections.deconstruction_radius + local dr2 = dr^2 + local dtile = config.corrections.deconstruction_tile + local pr = config.corrections.pattern_radius + local pr2 = pr^2 + local ptile = surface.get_tile(position).name + if ptile == 'deepwater' or ptile == 'water' then ptile = 'grass-1' end + local tiles_to_make = {} + for x = -pr, pr do -- loop over x + local x2 = x^2 + for y = -pr, pr do -- loop over y + local y2 = y^2 + local prod = x2+y2 + local p = {x=position.x+x,y=position.y+y} + if prod < dr2 then + -- if it is inside the decon radius + table.insert(tiles_to_make,{name=dtile,position=p}) + local entities_to_remove = surface.find_entities_filtered{area={{p.x-1,p.y-1},{p.x,p.y}}} + for _,entity in pairs(entities_to_remove) do + if entity.name ~= 'player' then entity.destroy() end + end + elseif prod < pr2 then + -- if it is inside the pattern radius + table.insert(tiles_to_make,{name=ptile,position=p}) + end + end + end + surface.set_tiles(tiles_to_make) +end + +-- generates the pattern that is in the config +local function spawn_pattern(surface,position) + local tiles_to_make = {} + local ptile = config.corrections.pattern_tile + local o = config.corrections.offset + local p = {x=position.x+o.x,y=position.y+o.y} + for _,tile in pairs(tiles) do + table.insert(tiles_to_make,{name=ptile,position={tile[1]+p.x,tile[2]+p.y}}) + end + surface.set_tiles(tiles_to_make) +end + +-- generates the entities that are in the config +local function spawn_entities(surface,position) + local o = config.corrections.offset + local p = {x=position.x+o.x,y=position.y+o.y} + for _,entity in pairs(entities) do + entity = surface.create_entity{name=entity[1],position={entity[2]+p.x,entity[3]+p.y},force='neutral'} + protect_entity(entity) + entity.operable = true + end +end + +local refill_time = 60*60*5 -- 5 minutes +Event.on_nth_tick(refill_time,function() + if game.tick < 10 then return end + spawn_turrets() +end) + +Event.add(defines.events.on_player_created, function(event) + if not event.player_index == 1 then return end + local player = Game.get_player_by_index(event.player_index) + spawn_base(player.surface,player.position) + spawn_pattern(player.surface,player.position) + get_spawn_force() + spawn_entities(player.surface,player.position) + spawn_turrets() + spawn_belts(player.surface) +end) \ No newline at end of file diff --git a/old/modules/SpawnArea/control.lua b/old/modules/DONE/SpawnArea/control.lua similarity index 100% rename from old/modules/SpawnArea/control.lua rename to old/modules/DONE/SpawnArea/control.lua diff --git a/old/modules/SpawnArea/softmod.json b/old/modules/DONE/SpawnArea/softmod.json similarity index 100% rename from old/modules/SpawnArea/softmod.json rename to old/modules/DONE/SpawnArea/softmod.json diff --git a/old/modules/SpawnArea/src/spawn_entities.lua b/old/modules/DONE/SpawnArea/src/spawn_entities.lua similarity index 100% rename from old/modules/SpawnArea/src/spawn_entities.lua rename to old/modules/DONE/SpawnArea/src/spawn_entities.lua diff --git a/old/modules/SpawnArea/src/spawn_tiles.lua b/old/modules/DONE/SpawnArea/src/spawn_tiles.lua similarity index 100% rename from old/modules/SpawnArea/src/spawn_tiles.lua rename to old/modules/DONE/SpawnArea/src/spawn_tiles.lua From 15bc0e033b51f352528476601ae25b2c064f51b2 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 25 Mar 2019 20:22:18 +0000 Subject: [PATCH 14/18] Added item return to spawn for corpes --- config/death_logger.lua | 2 +- expcore/common.lua | 12 ++++++------ modules/addons/death-logger.lua | 10 +++++++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/config/death_logger.lua b/config/death_logger.lua index 4b5ba5f5..53f8187a 100644 --- a/config/death_logger.lua +++ b/config/death_logger.lua @@ -5,7 +5,7 @@ return { --allow_teleport_to_body_command=false, -- allows use of /return-to-body which teleports you to your last death --allow_collect_bodies_command=false, -- allows use of /collect-body which returns all your items to you and removes the body --use_chests_as_bodies=false, -- weather items should be moved into a chest when a player dies - --auto_collect_bodies=false, -- enables items being returned to the spawn point in chests upon death + auto_collect_bodies=true, -- enables items being returned to the spawn point in chests upon corpse expiring show_map_markers=true, -- shows markers on the map where bodies are include_time_of_death=true, -- weather to include the time of death on the map marker map_icon=nil -- the icon that the map marker shows; nil means no icon; format as a SingleID diff --git a/expcore/common.lua b/expcore/common.lua index b3dbb28a..ab66e63f 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -221,15 +221,15 @@ function Public.format_time(ticks,options) end --- Moves items to the position and stores them in the closest entity of the type given --- @tparam items table items which are to be added to the chests, {name='item-name',count=100} +-- @tparam items table items which are to be added to the chests, ['name']=count -- @tparam[opt=navies] surface LuaSurface the surface that the items will be moved to -- @tparam[opt={0,0}] position table the position that the items will be moved to {x=100,y=100} -- @tparam[opt=32] radius number the radius in which the items are allowed to be placed function Public.move_items(items,surface,position,radius,chest_type) chest_type = chest_type or 'iron-chest' surface = surface or game.surfaces[1] - if type(position) == 'table' then return end - if type(items) == 'table' then return end + if type(position) ~= 'table' then return end + if type(items) ~= 'table' then return end -- Finds all entities of the given type local p = position or {x=0,y=0} local r = radius or 32 @@ -260,10 +260,10 @@ function Public.move_items(items,surface,position,radius,chest_type) end end -- Inserts the items into the chests - for _,item in pairs(items) do - local chest = next_chest(item) + for item_name,item_count in pairs(items) do + local chest = next_chest{name=item_name,count=item_count} if not chest then return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius',item.name,surface.name,p.x,p.y)) end - Util.insert_safe(chest,item) + Util.insert_safe(chest,{[item_name]=item_count}) end end diff --git a/modules/addons/death-logger.lua b/modules/addons/death-logger.lua index 4743b99d..9ffb31cf 100644 --- a/modules/addons/death-logger.lua +++ b/modules/addons/death-logger.lua @@ -2,7 +2,7 @@ local Event = require 'utils.event' local Game = require 'utils.game' local Global = require 'utils.global' local config = require 'config.death_logger' -local format_time = ext_require('expcore.common','format_time') +local format_time,move_items = ext_require('expcore.common','format_time','move_items') local deaths = { archive={} -- deaths moved here after body is gone @@ -78,6 +78,14 @@ if config.show_map_markers then end) end +if config.auto_collect_bodies then + Event.add(defines.events.on_character_corpse_expired,function(event) + local corpse = event.corpse + local items = corpse.get_inventory(defines.inventory.character_corpse).get_contents() + move_items(items,corpse.surface,{x=0,y=0}) + end) +end + -- this is so other modules can access the logs return function() return deaths From ea1de6a2b46f00ea68d31edcffdad9d09aff7fe3 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 25 Mar 2019 20:32:17 +0000 Subject: [PATCH 15/18] Added use chests as bodies --- config/death_logger.lua | 2 +- expcore/common.lua | 5 ++++- modules/addons/death-logger.lua | 7 +++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/config/death_logger.lua b/config/death_logger.lua index 53f8187a..7e03c2bb 100644 --- a/config/death_logger.lua +++ b/config/death_logger.lua @@ -4,7 +4,7 @@ return { --allow_teleport_to_body_command=false, -- allows use of /return-to-body which teleports you to your last death --allow_collect_bodies_command=false, -- allows use of /collect-body which returns all your items to you and removes the body - --use_chests_as_bodies=false, -- weather items should be moved into a chest when a player dies + use_chests_as_bodies=false, -- weather items should be moved into a chest when a player dies auto_collect_bodies=true, -- enables items being returned to the spawn point in chests upon corpse expiring show_map_markers=true, -- shows markers on the map where bodies are include_time_of_death=true, -- weather to include the time of death on the map marker diff --git a/expcore/common.lua b/expcore/common.lua index ab66e63f..aa70892a 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -239,7 +239,7 @@ function Public.move_items(items,surface,position,radius,chest_type) -- Makes a new emtpy chest when it is needed local function make_new_chest() local pos = surface.find_non_colliding_position(chest_type,position,32,1) - local chest = surface.surface.create_entity{name=chest_type,position=pos} + local chest = surface.create_entity{name=chest_type,position=pos,force='neutral'} table.insert(entities,chest) count = count + 1 return chest @@ -260,11 +260,14 @@ function Public.move_items(items,surface,position,radius,chest_type) end end -- Inserts the items into the chests + local last_chest for item_name,item_count in pairs(items) do local chest = next_chest{name=item_name,count=item_count} if not chest then return error(string.format('Cant move item %s to %s{%s, %s} no valid chest in radius',item.name,surface.name,p.x,p.y)) end Util.insert_safe(chest,{[item_name]=item_count}) + last_chest = chest end + return last_chest end return Public \ No newline at end of file diff --git a/modules/addons/death-logger.lua b/modules/addons/death-logger.lua index 9ffb31cf..938e550f 100644 --- a/modules/addons/death-logger.lua +++ b/modules/addons/death-logger.lua @@ -58,6 +58,13 @@ end Event.add(defines.events.on_player_died,function(event) local player = Game.get_player_by_index(event.player_index) local corpse = player.surface.find_entity('character-corpse',player.position) + if config.use_chests_as_bodies then + local items = corpse.get_inventory(defines.inventory.character_corpse).get_contents() + local chest = move_items(items,corpse.surface,corpse.position) + chest.destructible = false + corpse.destroy() + corpse = chest + end local death = { player_name = player.name, time_of_death = event.tick, From 660397a6d76bc36c7eca80623204f8a2cc01d670 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 25 Mar 2019 21:27:43 +0000 Subject: [PATCH 16/18] Added compi :D --- config/compilatron.lua | 21 +++++++ config/file_loader.lua | 1 + locale/en/addons.cfg | 23 +++++++- modules/addons/addons.cfg | 7 --- modules/addons/compilatron.lua | 100 +++++++++++++++++++++++++++++++++ modules/commands/commands.cfg | 10 ---- 6 files changed, 144 insertions(+), 18 deletions(-) create mode 100644 config/compilatron.lua delete mode 100644 modules/addons/addons.cfg create mode 100644 modules/addons/compilatron.lua delete mode 100644 modules/commands/commands.cfg diff --git a/config/compilatron.lua b/config/compilatron.lua new file mode 100644 index 00000000..a4980f92 --- /dev/null +++ b/config/compilatron.lua @@ -0,0 +1,21 @@ +return { + message_cycle=60*15, -- 15 seconds default, how often (in ticks) the messages will cycle + locations={ -- defines the spawn locations for all compilatrons + ['Spawn']={x=0,y=0} + }, + messages={ -- the messages that each one will say, must be same name as its location + ['Spawn']={ + {'info.website-message'}, + {'info.read-readme'}, + {'info.discord-message'}, + {'info.softmod'}, + {'info.wiki-message'}, + {'info.redmew'}, + {'info.feedback-message'}, + {'info.custom-commands'}, + {'info.status-message'}, + {'info.lhd'}, + {'info.github-message'}, + } + } +} \ No newline at end of file diff --git a/config/file_loader.lua b/config/file_loader.lua index 72802122..048cbd72 100644 --- a/config/file_loader.lua +++ b/config/file_loader.lua @@ -20,6 +20,7 @@ return { 'modules.addons.death-logger', 'modules.addons.advanced-starting-items', 'modules.addons.spawn-area', + 'modules.addons.compilatron', -- Config Files 'config.command_auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.command_auth_runtime_disable', -- allows commands to be enabled and disabled during runtime diff --git a/locale/en/addons.cfg b/locale/en/addons.cfg index a4bb08a6..d2d99105 100644 --- a/locale/en/addons.cfg +++ b/locale/en/addons.cfg @@ -4,4 +4,25 @@ ping=You have been mentioned in chat by __1__. [damage-popup] player-health=__1__ -player-damage=__1__ \ No newline at end of file +player-damage=__1__ + +[info] +players-online=There are __1__ players online +total-map-time=This map has been on for __1__ +discord-link=https://discord.explosivegaming.nl +discord-message=Join use on our discord at: https://discord.explosivegaming.nl +website-link=https://www.explosivegaming.nl +website-message=Please vist our website at: https://www.explosivegaming.nl +wiki-link=https://wiki.explosivegaming.nl/ +wiki-message=You can get more information about us and the custom scenario from our wiki: https://wiki.explosivegaming.nl/ +feedback-link=https://exp.fider.io/ +feedback-message=Do you have feedback? leave it at https://exp.fider.io/ +status-link=https://status.explosivegaming.nl +status-message=Want to check if out servers are down, vist: https://status.explosivegaming.nl +github-link=https://github.com/explosivegaming/scenario +github-message=Want to help improve our server with some extra features? Help us at: https://github.com/explosivegaming/scenario +custom-commands=We use custom commands, such as /tag and /me, use /chelp for more info. +read-readme=Make sure you have read the Readme (It can be found through the question mark on the top left) +softmod=We run a softmod on our servers. A softmod is a custom scenario that runs on this server, example is the player list. +redmew=We dont talk about redmew here; they beat us to 1000 members ;-; +lhd=All trains must be LHD! This is a long standing rule on our servers, please resepect this. \ No newline at end of file diff --git a/modules/addons/addons.cfg b/modules/addons/addons.cfg deleted file mode 100644 index a4bb08a6..00000000 --- a/modules/addons/addons.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[chat-popup] -message=__1__: __2__ -ping=You have been mentioned in chat by __1__. - -[damage-popup] -player-health=__1__ -player-damage=__1__ \ No newline at end of file diff --git a/modules/addons/compilatron.lua b/modules/addons/compilatron.lua new file mode 100644 index 00000000..dec30416 --- /dev/null +++ b/modules/addons/compilatron.lua @@ -0,0 +1,100 @@ +local Event = require 'utils.event' +local Global = require 'utils.global' +local Game = require 'utils.game' +local Task = require 'utils.task' +local Token = require 'utils.token' +local config = require 'config.compilatron' +local messages = config.messages +local locations = config.locations + +local compilatrons = {} +local current_messages = {} +Global.register( + { + compilatrons = compilatrons, + current_messages = current_messages + }, + function(tbl) + compilatrons = tbl.compilatrons + current_messages = tbl.current_messages + end +) + +--- This will re-create the speech bubble after it de-spawns called with set_timeout +local callback = + Token.register( + function(data) + local ent = data.ent + local name = data.name + local msg_number = data.msg_number + local message = + ent.surface.create_entity( + {name = 'compi-speech-bubble', text = messages[name][msg_number], position = {0, 0}, source = ent} + ) + current_messages[name] = {message = message, msg_number = msg_number} + end +) + +--- This will move the messages onto the next message in the loop +local function circle_messages() + for name, ent in pairs(compilatrons) do + local current_message = current_messages[name] + local msg_number + local message + if current_message ~= nil then + message = current_message.message + if message ~= nil then + message.destroy() + end + msg_number = current_message.msg_number + msg_number = (msg_number < #messages[name]) and msg_number + 1 or 1 + else + msg_number = 1 + end + -- this calls the callback above to re-spawn the message after some time + Task.set_timeout_in_ticks(300, callback, {ent = ent, name = name, msg_number = msg_number}) + end +end + +Event.on_nth_tick(config.message_cycle, circle_messages) + +local Public = {} + +--- This will add a compilatron to the global and start his message cycle +-- @tparam entity LuaEntity the compilatron entity that moves around +-- @tparam name string the name of the location that the complitron is at +function Public.add_compilatron(entity, name) + if not entity and not entity.valid then + return + end + if name == nil then + return + end + compilatrons[name] = entity + local message = + entity.surface.create_entity( + {name = 'compi-speech-bubble', text = messages[name][1], position = {0, 0}, source = entity} + ) + current_messages[name] = {message = message, msg_number = 1} +end + +--- This spawns a new compilatron on a surface with the given location tag (not a position) +-- @tparam surface LuaSurface the surface to spawn the compilatron on +-- @tparam location string the location tag that is in the config file +function Public.spawn_compilatron(surface,location) + local position = locations[location] + local pos = surface.find_non_colliding_position('compilatron', position, 1.5, 0.5) + local compi = surface.create_entity {name='compilatron',position=pos,force=game.forces.neutral} + Public.add_compilatron(compi,location) +end + +-- When the first player is created this will create all comilatrons that are resisted in the config +Event.add(defines.events.on_player_created,function(event) + if not event.player_index == 1 then return end + local player = Game.get_player_by_index(event.player_index) + for location,pos in pairs(locations) do + Public.spawn_compilatron(player.surface,location) + end +end) + +return Public diff --git a/modules/commands/commands.cfg b/modules/commands/commands.cfg deleted file mode 100644 index ddf4213b..00000000 --- a/modules/commands/commands.cfg +++ /dev/null @@ -1,10 +0,0 @@ -[exp-commands] -kill-already-dead=You are already dead. -admin-chat-format=[Admin Chat] [color=__3__]__1__: __2__ -tp-no-position-found=No position to teleport to was found, please try again later. -tp-to-self=Player can not be teleported to themselves. -chelp-title=Help results for "__1__": -chelp-footer=(__1__ results found; page __2__ of __3__) -chelp-format=/__1__ __2__ - __3__ __4__ -chelp-alias=Alias: __1__ -chelp-out-of-range=__1__ is an invalid page number. \ No newline at end of file From bf97096dd77beabd747de89a50bc2390fa1ce773 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 28 Mar 2019 22:47:51 +0000 Subject: [PATCH 17/18] Added Paths --- config/file_loader.lua | 1 + config/worn_paths.lua | 112 +++++++++++++ expcore/common.lua | 150 ++++++++++++++++++ modules/addons/worn-paths.lua | 125 +++++++++++++++ old/modules/{ => DONE}/WornPaths/control.lua | 0 old/modules/{ => DONE}/WornPaths/softmod.json | 0 .../{ => DONE}/WornPaths/src/entites.lua | 0 .../{ => DONE}/WornPaths/src/paths.lua | 0 .../{ => DONE}/WornPaths/src/placed.lua | 0 9 files changed, 388 insertions(+) create mode 100644 config/worn_paths.lua create mode 100644 modules/addons/worn-paths.lua rename old/modules/{ => DONE}/WornPaths/control.lua (100%) rename old/modules/{ => DONE}/WornPaths/softmod.json (100%) rename old/modules/{ => DONE}/WornPaths/src/entites.lua (100%) rename old/modules/{ => DONE}/WornPaths/src/paths.lua (100%) rename old/modules/{ => DONE}/WornPaths/src/placed.lua (100%) diff --git a/config/file_loader.lua b/config/file_loader.lua index 048cbd72..3a85a462 100644 --- a/config/file_loader.lua +++ b/config/file_loader.lua @@ -21,6 +21,7 @@ return { 'modules.addons.advanced-starting-items', 'modules.addons.spawn-area', 'modules.addons.compilatron', + 'modules.addons.worn-paths', -- Config Files 'config.command_auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.command_auth_runtime_disable', -- allows commands to be enabled and disabled during runtime diff --git a/config/worn_paths.lua b/config/worn_paths.lua new file mode 100644 index 00000000..f498721d --- /dev/null +++ b/config/worn_paths.lua @@ -0,0 +1,112 @@ +--- This file controls the placement/degrading of tiles as players build and walk +return { + weakness_value=1000, -- lower value will make tiles more likely to degrade + strengths={ -- this decides how "strong" a tile is, bigger number means less likely to degrade + -- note: tiles are effected by the tiles around them, a two wide path of the highest value will not degrade (for weakness 6) + -- note: values are relative to the tile with the highest value, recommended to keep highest tile as a "nice" number + -- note: tiles not in list will never degrade under any conditions (which is why some are omitted such as water) + ["refined-concrete"]=100, + ["refined-hazard-concrete-left"]=100, + ["refined-hazard-concrete-right"]=100, + ["concrete"]=90, + ["hazard-concrete-left"]=90, + ["hazard-concrete-right"]=90, + ["stone-path"]=80, + ["red-desert-0"]=80, + ["dry-dirt"]=50, + -- grass four (main grass tiles) + ["grass-1"]=50, + ["grass-2"]=40, + ["grass-3"]=30, + ["grass-4"]=25, + -- red three (main red tiles) + ["red-desert-1"]=40, + ["red-desert-2"]=30, + ["red-desert-3"]=25, + -- sand three (main sand tiles) + ["sand-1"]=40, + ["sand-2"]=30, + ["sand-3"]=25, + -- dirt 3 (main dirt tiles) + ["dirt-1"]=40, + ["dirt-2"]=30, + ["dirt-3"]=25, + -- last three/four (all sets of three merge here) + ["dirt-4"]=25, + ["dirt-5"]=30, + ["dirt-6"]=40, + --["dirt-7"]=0, -- last tile, nothing to degrade to + -- land fill chain + ["landfill"]=95, + ["water-shallow"]=90, + --["water-mud"]=0, -- last tile, nothing to degrade to + }, + degrade_order={ -- when a tile degrades it will turn into the next tile given here + ["refined-concrete"]='concrete', + ["refined-hazard-concrete-left"]='hazard-concrete-left', + ["refined-hazard-concrete-right"]='hazard-concrete-right', + ["concrete"]='stone-path', + ["hazard-concrete-left"]='stone-path', + ["hazard-concrete-right"]='stone-path', + ["stone-path"]='dry-dirt', + ["red-desert-0"]='dry-dirt', + ["dry-dirt"]='dirt-4', + -- grass four (main grass tiles) + ["grass-1"]='grass-2', + ["grass-2"]='grass-3', + ["grass-3"]='grass-4', + ["grass-4"]='dirt-4', + -- red three (main red tiles) + ["red-desert-1"]='red-desert-2', + ["red-desert-2"]='red-desert-3', + ["red-desert-3"]='dirt-4', + -- sand three (main sand tiles) + ["sand-1"]='sand-2', + ["sand-2"]='sand-3', + ["sand-3"]='dirt-4', + -- dirt 3 (main dirt tiles) + ["dirt-1"]='dirt-2', + ["dirt-2"]='dirt-3', + ["dirt-3"]='dirt-4', + -- last three/four (all sets of three merge here) + ["dirt-4"]='dirt-5', + ["dirt-5"]='dirt-6', + ["dirt-6"]='dirt-7', + --["dirt-7"]=0, -- last tile, nothing to degrade to + -- land fill chain + ["landfill"]='water-shallow', + ["water-shallow"]='water-mud', + --["water-mud"]=0, -- last tile, nothing to degrade to + }, + entities={ -- entities in this list will degrade the tiles under them when they are placed + ['stone-furnace']=true, + ['steel-furnace']=true, + ['electric-furnace']=true, + ['assembling-machine-1']=true, + ['assembling-machine-2']=true, + ['assembling-machine-3']=true, + ['beacon']=true, + ['centrifuge']=true, + ['chemical-plant']=true, + ['oil-refinery']=true, + ['storage-tank']=true, + ['nuclear-reactor']=true, + ['steam-engine']=true, + ['steam-turbine']=true, + ['boiler']=true, + ['heat-exchanger']=true, + ['stone-wall']=true, + ['gate']=true, + ['gun-turret']=true, + ['laser-turret']=true, + ['flamethrower-turret']=true, + ['radar']=true, + ['lab']=true, + ['big-electric-pole']=true, + ['substation']=true, + ['rocket-silo']=true, + ['pumpjack']=true, + ['electric-mining-drill']=true, + ['roboport']=true + } +} \ No newline at end of file diff --git a/expcore/common.lua b/expcore/common.lua index aa70892a..4b5aee81 100644 --- a/expcore/common.lua +++ b/expcore/common.lua @@ -270,4 +270,154 @@ function Public.move_items(items,surface,position,radius,chest_type) return last_chest end +--[[-- https://github.com/Refactorio/RedMew/blob/9184b2940f311d8c9c891e83429fc57ec7e0c4a2/map_gen/maps/diggy/debug.lua#L31 + Prints a colored value on a location. + @param value between -1 and 1 + @param surface LuaSurface + @param position Position {x, y} + @param scale float + @param offset float + @param immutable bool if immutable, only set, never do a surface lookup, values never change +]] +function Public.print_grid_value(value, surface, position, scale, offset, immutable) + local is_string = type(value) == 'string' + local color = Colours.white + local text = value + + if type(immutable) ~= 'boolean' then + immutable = false + end + + if not is_string then + scale = scale or 1 + offset = offset or 0 + position = {x = position.x + offset, y = position.y + offset} + local r = math.max(1, value) / scale + local g = 1 - math.abs(value) / scale + local b = math.min(1, value) / scale + + if (r > 0) then + r = 0 + end + + if (b < 0) then + b = 0 + end + + if (g < 0) then + g = 0 + end + + r = math.abs(r) + + color = { r = r, g = g, b = b} + + -- round at precision of 2 + text = math.floor(100 * value) * 0.01 + + if (0 == text) then + text = '0.00' + end + end + + if not immutable then + local text_entity = surface.find_entity('flying-text', position) + + if text_entity then + text_entity.text = text + text_entity.color = color + return + end + end + + surface.create_entity{ + name = 'flying-text', + color = color, + text = text, + position = position + }.active = false +end + +--[[-- + Prints a colored value on a location. When given a color_value and a delta_color, + will change the color of the text from the base to base + value * delta. This will + make the color of the text range from 'base_color' to 'base_color + delta_color' + as the color_value ranges from 0 to 1 + @param value of number to be displayed + @param surface LuaSurface + @param position Position {x, y} + @param offset float position offset + @param immutable bool if immutable, only set, never do a surface lookup, values never change + @param color_value float How far along the range of values of colors the value is to be displayed + @param base_color {r,g,b} The color for the text to be if color_value is 0 + @param delta_color {r,g,b} The amount to correct the base_color if color_value is 1 + @param under_bound {r,g,b} The color to be used if color_value < 0 + @param over_bound {r,g,b} The color to be used if color_value > 1 +]] +function Public.print_colored_grid_value(value, surface, position, offset, immutable, + color_value, base_color, delta_color, under_bound, over_bound) + local is_string = type(value) == 'string' + -- default values: + local color = base_color or Colours.white + local d_color = delta_color or Colours.black + local u_color = under_bound or color + local o_color = over_bound or color + + if (color_value < 0) then + color = u_color + elseif (color_value > 1) then + color = o_color + else + color = { + r = color.r + color_value * d_color.r, + g = color.g + color_value * d_color.g, + b = color.b + color_value * d_color.b + } + end + + local text = value + + if type(immutable) ~= 'boolean' then + immutable = false + end + + if not is_string then + offset = offset or 0 + position = {x = position.x + offset, y = position.y + offset} + + -- round at precision of 2 + text = math.floor(100 * value) * 0.01 + + if (0 == text) then + text = '0.00' + end + end + + if not immutable then + local text_entity = surface.find_entity('flying-text', position) + + if text_entity then + text_entity.text = text + text_entity.color = color + return + end + end + + surface.create_entity{ + name = 'flying-text', + color = color, + text = text, + position = position + }.active = false +end + +function Public.clear_flying_text(surface) + local entities = surface.find_entities_filtered{name ='flying-text'} + for _,entity in pairs(entities) do + if entity and entity.valid then + entity.destroy() + end + end +end + return Public \ No newline at end of file diff --git a/modules/addons/worn-paths.lua b/modules/addons/worn-paths.lua new file mode 100644 index 00000000..fef49a2d --- /dev/null +++ b/modules/addons/worn-paths.lua @@ -0,0 +1,125 @@ +local Event = require 'utils.event' +local Game = require 'utils.game' +local Global = require 'utils.global' +local print_grid_value, clear_flying_text = ext_require('expcore.common','print_grid_value','clear_flying_text') +local config = require 'config.worn_paths' + +local max_strength = 0 +for _,strength in pairs(config.strengths) do + if strength > max_strength then + max_strength = strength + end +end + +local debug_players = {} +Global.register(debug_players, function(tbl) + debug_players = tbl +end) + +local function degrade(surface,position) + local tile = surface.get_tile(position) + local tile_name = tile.name + local degrade_tile_name = config.degrade_order[tile_name] + if not degrade_tile_name then return end + surface.set_tiles{{name=degrade_tile_name,position=position}} +end + +local function degrade_entity(entity) + local surface = entity.surface + local position = entity.position + local tiles = {} + if not config.entities[entity.name] then return end + local box = entity.prototype.collision_box + local lt = box.left_top + local rb = box.right_bottom + for x = lt.x, rb.x do -- x loop + local px = position.x+x + for y = lt.y, rb.y do -- y loop + local p = {x=px,y=position.y+y} + local tile = surface.get_tile(p) + local tile_name = tile.name + local degrade_tile_name = config.degrade_order[tile_name] + if not degrade_tile_name then return end + table.insert(tiles,{name=degrade_tile_name,position=p}) + end + end + surface.set_tiles(tiles) +end + +local function get_probability(strength) + local v1 = strength/max_strength + local dif = 1 - v1 + local v2 = dif/2 + return (1-v1+v2)/config.weakness_value +end + +local function get_tile_strength(surface,position) + local tile = surface.get_tile(position) + local tile_name = tile.name + local strength = config.strengths[tile_name] + if not strength then return end + for x = -1,1 do -- x loop + local px = position.x + x + for y = -1,1 do -- y loop + local check_tile = surface.get_tile{x=px,y=position.y+y} + local check_tile_name = check_tile.name + local check_strength = config.strengths[check_tile_name] or 0 + strength = strength + check_strength + end + end + return strength/9 +end + +local function debug_get_tile_strength(surface,position) + for x = -3,3 do -- x loop + local px = position.x+x + for y = -3,3 do -- y loop + local p = {x=px,y=position.y+y} + local strength = get_tile_strength(surface,p) or 0 + local tile = surface.get_tile(p) + print_grid_value(get_probability(strength)*config.weakness_value, surface, tile.position) + end + end +end + +Event.add(defines.events.on_player_changed_position, function(event) + local player = Game.get_player_by_index(event.player_index) + local surface = player.surface + local position = player.position + local strength = get_tile_strength(surface,position) + if not strength then return end + if get_probability(strength) > math.random() then + degrade(surface,position) + end + if debug_players[player.name] then + debug_get_tile_strength(surface,position) + end +end) + +Event.add(defines.events.on_built_entity, function(event) + local entity = event.created_entity + local surface = entity.surface + local position = entity.position + local strength = get_tile_strength(surface,position) + if not strength then return end + if get_probability(strength)*config.weakness_value > math.random() then + degrade_entity(entity) + end +end) + +Event.add(defines.events.on_robot_built_entity, function(event) + local entity = event.created_entity + local surface = entity.surface + local position = entity.position + local strength = get_tile_strength(surface,position) + if not strength then return end + if get_probability(strength)*config.weakness_value > math.random() then + degrade_entity(entity) + end +end) + +return function(player_name,state) + local player = Game.get_player_from_any(player_name) + clear_flying_text(player.surface) + debug_players[player_name] = state +end \ No newline at end of file diff --git a/old/modules/WornPaths/control.lua b/old/modules/DONE/WornPaths/control.lua similarity index 100% rename from old/modules/WornPaths/control.lua rename to old/modules/DONE/WornPaths/control.lua diff --git a/old/modules/WornPaths/softmod.json b/old/modules/DONE/WornPaths/softmod.json similarity index 100% rename from old/modules/WornPaths/softmod.json rename to old/modules/DONE/WornPaths/softmod.json diff --git a/old/modules/WornPaths/src/entites.lua b/old/modules/DONE/WornPaths/src/entites.lua similarity index 100% rename from old/modules/WornPaths/src/entites.lua rename to old/modules/DONE/WornPaths/src/entites.lua diff --git a/old/modules/WornPaths/src/paths.lua b/old/modules/DONE/WornPaths/src/paths.lua similarity index 100% rename from old/modules/WornPaths/src/paths.lua rename to old/modules/DONE/WornPaths/src/paths.lua diff --git a/old/modules/WornPaths/src/placed.lua b/old/modules/DONE/WornPaths/src/placed.lua similarity index 100% rename from old/modules/WornPaths/src/placed.lua rename to old/modules/DONE/WornPaths/src/placed.lua From 9a1d93071fc8934c688ef6f905cd12bed8c9d214 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Fri, 29 Mar 2019 15:44:50 +0000 Subject: [PATCH 18/18] Added comments to worn_paths --- config/worn_paths.lua | 8 ++++---- modules/addons/worn-paths.lua | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/config/worn_paths.lua b/config/worn_paths.lua index f498721d..8a72aa73 100644 --- a/config/worn_paths.lua +++ b/config/worn_paths.lua @@ -37,8 +37,8 @@ return { ["dirt-6"]=40, --["dirt-7"]=0, -- last tile, nothing to degrade to -- land fill chain - ["landfill"]=95, - ["water-shallow"]=90, + ["landfill"]=50, + --["water-shallow"]=90, --["water-mud"]=0, -- last tile, nothing to degrade to }, degrade_order={ -- when a tile degrades it will turn into the next tile given here @@ -74,8 +74,8 @@ return { ["dirt-6"]='dirt-7', --["dirt-7"]=0, -- last tile, nothing to degrade to -- land fill chain - ["landfill"]='water-shallow', - ["water-shallow"]='water-mud', + ["landfill"]='grass-2', -- 'water-shallow' + --["water-shallow"]='water-mud', --["water-mud"]=0, -- last tile, nothing to degrade to }, entities={ -- entities in this list will degrade the tiles under them when they are placed diff --git a/modules/addons/worn-paths.lua b/modules/addons/worn-paths.lua index fef49a2d..2d301a3d 100644 --- a/modules/addons/worn-paths.lua +++ b/modules/addons/worn-paths.lua @@ -4,6 +4,7 @@ local Global = require 'utils.global' local print_grid_value, clear_flying_text = ext_require('expcore.common','print_grid_value','clear_flying_text') local config = require 'config.worn_paths' +-- Loops over the config and finds the wile which has the highest value for strength local max_strength = 0 for _,strength in pairs(config.strengths) do if strength > max_strength then @@ -11,11 +12,13 @@ for _,strength in pairs(config.strengths) do end end +-- Used for debugging the degrade chances local debug_players = {} Global.register(debug_players, function(tbl) debug_players = tbl end) +-- Will degrade a tile down to the next tile when called local function degrade(surface,position) local tile = surface.get_tile(position) local tile_name = tile.name @@ -24,6 +27,7 @@ local function degrade(surface,position) surface.set_tiles{{name=degrade_tile_name,position=position}} end +-- Same as degrade but will degrade all tiles that are under an entity local function degrade_entity(entity) local surface = entity.surface local position = entity.position @@ -46,6 +50,7 @@ local function degrade_entity(entity) surface.set_tiles(tiles) end +-- Turns the strength of a tile into a probability (0 = impossible, 1 = certain) local function get_probability(strength) local v1 = strength/max_strength local dif = 1 - v1 @@ -53,6 +58,7 @@ local function get_probability(strength) return (1-v1+v2)/config.weakness_value end +-- Gets the mean of the strengths around a tile to give the strength at that position local function get_tile_strength(surface,position) local tile = surface.get_tile(position) local tile_name = tile.name @@ -70,6 +76,7 @@ local function get_tile_strength(surface,position) return strength/9 end +-- Same as get_tile_strength but returns to a in game text rather than as a value local function debug_get_tile_strength(surface,position) for x = -3,3 do -- x loop local px = position.x+x @@ -82,6 +89,7 @@ local function debug_get_tile_strength(surface,position) end end +-- When the player changes position the tile will have a chance to downgrade, debug check is here Event.add(defines.events.on_player_changed_position, function(event) local player = Game.get_player_by_index(event.player_index) local surface = player.surface @@ -96,6 +104,7 @@ Event.add(defines.events.on_player_changed_position, function(event) end end) +-- When an entity is build there is a much higher chance that the tiles will degrade Event.add(defines.events.on_built_entity, function(event) local entity = event.created_entity local surface = entity.surface @@ -107,6 +116,7 @@ Event.add(defines.events.on_built_entity, function(event) end end) +-- Same as above but with robots Event.add(defines.events.on_robot_built_entity, function(event) local entity = event.created_entity local surface = entity.surface @@ -118,6 +128,7 @@ Event.add(defines.events.on_robot_built_entity, function(event) end end) +-- Used as a way to access the global table return function(player_name,state) local player = Game.get_player_from_any(player_name) clear_flying_text(player.surface)