1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-10-30 23:47:41 +02:00

Changes for utils.

This commit is contained in:
hanakocz
2024-09-30 23:05:53 +02:00
committed by Gerkiz
parent 8b932b663f
commit ec5dc174b1
5 changed files with 202 additions and 83 deletions

View File

@@ -0,0 +1,30 @@
local Public = {}
---Create Flying text for the player, or for all players on that surface if no player specified
---@param player LuaPlayer|nil
---@param surface LuaSurface
---@param position MapPosition
---@param text string|table
---@param color Color|table
function Public.flying_text(player, surface, position, text, color)
if not player then
for _, player in pairs(game.connected_players) do
if player.surface == surface then
player.create_local_flying_text({
text = text,
position = position,
color = color
})
end
end
else
player.create_local_flying_text({
text = text,
position = position,
color = color
})
end
end
return Public

View File

@@ -92,7 +92,7 @@ local function unearthing_biters(surface, position, amount, relative_evolution)
return
end
local evolution = game.forces.enemy.evolution_factor
local evolution = game.forces['enemy'].get_evolution_factor(surface)
if relative_evolution then
evolution = relative_evolution

View File

@@ -142,8 +142,7 @@ local function unearthing_worm(surface, position, relative_evolution)
if not position.y then
return
end
local evolution_index = math.ceil(game.forces.enemy.evolution_factor * 10)
local evolution_index = math.ceil(game.forces['enemy'].get_evolution_factor(surface) * 10)
if relative_evolution then
evolution_index = math.ceil(relative_evolution * 10)

View File

@@ -1,6 +1,7 @@
---@diagnostic disable: undefined-field
--luacheck: globals table
local Stats = require 'utils.stats'
local Utils = require 'utils.utils'
local random = math.random
local floor = math.floor
local remove = table.remove
@@ -8,9 +9,9 @@ local tonumber = tonumber
local pairs = pairs
local table_size = table_size
--- Searches a table to remove a specific element without an index
-- @param t <table> to search
-- @param <any> table element to search for
---Searches a table to remove a specific element without an index
---@param t table #table to search
---@param element any #table element to search for
function table.remove_element(t, element)
for k, v in pairs(t) do
if v == element then
@@ -20,10 +21,10 @@ function table.remove_element(t, element)
end
end
--- Removes an item from an array in O(1) time.
-- The catch is that fast_remove doesn't guarantee to maintain the order of items in the array.
-- @param tbl <table> arrayed table
-- @param index <number> Must be >= 0. The case where index > #tbl is handled.
---Removes an item from an array in O(1) time.
---The catch is that fast_remove doesn't guarantee to maintain the order of items in the array.
---@param tbl table #arrayed table
---@param index number #Must be >= 0. The case where index > #tbl is handled.
function table.fast_remove(tbl, index)
local count = #tbl
if index > count then
@@ -35,9 +36,9 @@ function table.fast_remove(tbl, index)
tbl[count] = nil
end
--- Adds the contents of table t2 to table t1
-- @param t1 <table> to insert into
-- @param t2 <table> to insert from
---Adds the contents of table t2 to table t1
---@param t1 table #table to insert into
---@param t2 table #table to insert from
function table.add_all(t1, t2)
for k, v in pairs(t2) do
if tonumber(k) then
@@ -48,10 +49,10 @@ function table.add_all(t1, t2)
end
end
--- Checks if a table contains an element
-- @param t <table>
-- @param e <any> table element
-- @returns <any> the index of the element or nil
---Checks if a table contains an element
---@param t table
---@param e any #table element
---@return any #the index of the element or nil
function table.index_of(t, e)
for k, v in pairs(t) do
if v == e then
@@ -61,10 +62,10 @@ function table.index_of(t, e)
return nil
end
--- Checks if the arrayed portion of a table contains an element
-- @param t <table>
-- @param e <any> table element
-- @returns <number|nil> the index of the element or nil
---Checks if the arrayed portion of a table contains an element
---@param t table
---@param e any #table element
---@return number|nil #the index of the element or nil
function table.index_of_in_array(t, e)
for i = 1, #t do
if t[i] == e then
@@ -75,27 +76,27 @@ function table.index_of_in_array(t, e)
end
local index_of = table.index_of
--- Checks if a table contains an element
-- @param t <table>
-- @param e <any> table element
-- @returns <boolean> indicating success
---Checks if a table contains an element
---@param t table
---@param e any #table element
---@return boolean #boolean indicating success
function table.contains(t, e)
return index_of(t, e) and true or false
end
local index_of_in_array = table.index_of_in_array
--- Checks if the arrayed portion of a table contains an element
-- @param t <table>
-- @param e <any> table element
-- @returns <boolean> indicating success
---Checks if the arrayed portion of a table contains an element
---@param t table
---@param e any #table element
---@return boolean #boolean indicating success
function table.array_contains(t, e)
return index_of_in_array(t, e) and true or false
end
--- Adds an element into a specific index position while shuffling the rest down
-- @param t <table> to add into
-- @param index <number> the position in the table to add to
-- @param element <any> to add to the table
---Adds an element into a specific index position while shuffling the rest down
---@param t table #table to add into
---@param index number #index of the position in the table to add to
---@param element any #element to add to the table
function table.set(t, index, element)
local i = 1
for k in pairs(t) do
@@ -108,8 +109,8 @@ function table.set(t, index, element)
error('Index out of bounds', 2)
end
--- Returns an array of keys for a table.
--@param tbl <table>
---Returns an array of keys for a table.
---@param tbl table
function table.keys(tbl)
local n = 1
local keys = {}
@@ -122,11 +123,11 @@ function table.keys(tbl)
return keys
end
--- Chooses a random entry from a table
-- because this uses math.random, it cannot be used outside of events
-- @param t <table>
-- @param key <boolean> to indicate whether to return the key or value
-- @return <any> a random element of table t
---Chooses a random entry from a table.
---Because this uses math.random, it cannot be used outside of events
---@param t table
---@param key boolean #boolean to indicate whether to return the key or value
---@return any #a random element of table t
function table.get_random_dictionary_entry(t, key)
local target_index = random(1, table_size(t))
local count = 1
@@ -142,12 +143,12 @@ function table.get_random_dictionary_entry(t, key)
end
end
--- Chooses a random entry from a weighted table
-- because this uses math.random, it cannot be used outside of events
-- @param weighted_table <table> of tables with items and their weights
-- @param item_index <number> of the index of items, defaults to 1
-- @param weight_index <number> of the index of the weights, defaults to 2
-- @return <any> table element
---Chooses a random entry from a weighted table.
---Because this uses math.random, it cannot be used outside of events
---@param weighted_table table #table of tables with items and their weights
---@param item_index number|nil #number of the index of items, defaults to 1
---@param weight_index number|nil #number of the index of the weights, defaults to 2
---@return any # any table element
-- @see features.chat_triggers::hodor
function table.get_random_weighted(weighted_table, item_index, weight_index)
local total_weight = 0
@@ -168,9 +169,39 @@ function table.get_random_weighted(weighted_table, item_index, weight_index)
end
end
--- Returns a table with % chance values for each item of a weighted_table
-- @param weighted_table <table> of tables with items and their weights
-- @param weight_index <number> of the index of the weights, defaults to 2
---Returns one random value based on the supplied weights. Form {[a] = A, [b] = B, ...} and {[a] = a_weight, [b] = b_weight, ...} or just {a,b,c,...} and {1,2,1,...}.
---Both tables have to be the same size.
---@param values table
---@param weights table
---@return any
function table.get_random_weighted_t(values, weights)
local total_weight = 0
for k, w in pairs(weights) do
assert(values[k], 'Weighted_raffle: A weight is missing value!')
if w > 0 then
-- negative weights treated as zero
total_weight = total_weight + w
end
end
assert(total_weight > 0, 'Total weight of weighted_raffle needs to be bigger than zero!')
local cumulative_probability = 0
local rng = random()
for k, v in pairs(values) do
assert(weights[k], 'Weighted_raffle: A value is missing weight!')
cumulative_probability = cumulative_probability + (weights[k] / total_weight)
if rng <= cumulative_probability then
return v
end
end
end
---Returns a table with % chance values for each item of a weighted_table
---@param weighted_table table of tables with items and their weights
---@param weight_index number of the index of the weights, defaults to 2
---@return table
function table.get_random_weighted_chances(weighted_table, weight_index)
local total_weight = 0
weight_index = weight_index or 2
@@ -184,12 +215,13 @@ function table.get_random_weighted_chances(weighted_table, weight_index)
return chance_table
end
--- Creates a fisher-yates shuffle of a sequential number-indexed table
-- because this uses math.random, it cannot be used outside of events if no rng is supplied
-- from: http://www.sdknews.com/cross-platform/corona/tutorial-how-to-shuffle-table-items
-- @param t <table> to shuffle
---Creates a fisher-yates shuffle of a sequential number-indexed table.
---Because this uses math.random, it cannot be used outside of events if no rng is supplied
---from: http://www.sdknews.com/cross-platform/corona/tutorial-how-to-shuffle-table-items
---@param t table #table to shuffle
---@param rng number|nil
function table.shuffle_table(t, rng)
local rand = rng or math.random
local rand = rng or random
local iterations = #t
if iterations == 0 then
error('Not a sequential table')
@@ -203,9 +235,55 @@ function table.shuffle_table(t, rng)
end
end
---Shuffles a table of objects with a position, leaving objects closer to position to be earlier in the table (one time semi-sort)
---@param tbl table #table to shuffle, all elements in it have to be table objects that have position key
---@param position MapPosition|{x:double,y:double}
function table.shuffle_by_distance(tbl, position)
local function pos(obj)
if obj and obj.valid and obj.position then
return obj.position
end
error('entry was not valid or does not have position!', 2)
end
local size = #tbl
for i = size, 1, -1 do
local rand = random(size)
if Utils.is_closer(pos(tbl[i]), pos(tbl[rand]), position) and i > rand then
tbl[i], tbl[rand] = tbl[rand], tbl[i]
end
end
end
--- pairs() iterator but sorted by specified function
---@param t table
---@param order function # example: function(t,a,b) return t[b] > t[a] end
---@return function # usage: for k, v in spairs(table, function()) do ...
function table.spairs(t, order)
-- collect the keys
local keys = {}
for k in pairs(t) do keys[#keys+1] = k end
-- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys
if order then
table.sort(keys, function(a,b) return order(t, a, b) end)
else
table.sort(keys)
end
-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
--- Clears all existing entries in a table
-- @param t <table> to clear
-- @param array <boolean> to indicate whether the table is an array or not
---@param t table to clear
---@param array boolean to indicate whether the table is an array or not
function table.clear_table(t, array)
if array then
for i = 1, #t do

View File

@@ -1,13 +1,40 @@
local Module = {}
-- luacheck: ignore math
Module.distance = function (pos1, pos2)
---Returns cartesian distance between pos1 and pos2
---@param pos1 MapPosition|{x:double,y:double}
---@param pos2 MapPosition|{x:double,y:double}
---@return number
function Module.distance(pos1, pos2)
local dx = pos2.x - pos1.x
local dy = pos2.y - pos1.y
return math.sqrt(dx * dx + dy * dy)
end
-- rounds number (num) to certain number of decimal places (idp)
---Returns true if position is closer to pos1 than to pos2
---@param pos1 MapPosition|{x:double,y:double}
---@param pos2 MapPosition|{x:double,y:double}
---@param position MapPosition|{x:double,y:double}
---@return boolean
function Module.is_closer(position, pos1, pos2)
return Module.distance(pos1, position) < Module.distance(pos2, position)
end
---Returns true if the position is inside the area
---@param position MapPosition|{x:double,y:double}|nil
---@param area BoundingBox|{left_top:MapPosition, right_bottom:MapPosition}
---@return boolean
function Module.inside(position, area)
if not position then
return false
end
local lt = area.left_top
local rb = area.right_bottom
return position.x >= lt.x and position.y >= lt.y and position.x <= rb.x and position.y <= rb.y
end
---rounds number (num) to certain number of decimal places (idp)
function math.round(num, idp)
local mult = 10 ^ (idp or 0)
return math.floor(num * mult + 0.5) / mult
@@ -23,7 +50,7 @@ function math.clamp(num, min, max)
end
end
Module.print_except = function (msg, player)
function Module.print_except(msg, player)
for _, p in pairs(game.players) do
if p.connected and p ~= player then
p.print(msg)
@@ -31,7 +58,7 @@ Module.print_except = function (msg, player)
end
end
Module.print_admins = function (msg)
function Module.print_admins(msg)
for _, p in pairs(game.players) do
if p.connected and p.admin then
p.print(msg)
@@ -39,14 +66,14 @@ Module.print_admins = function (msg)
end
end
Module.get_actor = function ()
function Module.get_actor()
if game.player then
return game.player.name
end
return '<server>'
end
Module.cast_bool = function (var)
function Module.cast_bool(var)
if var then
return true
else
@@ -54,7 +81,7 @@ Module.cast_bool = function (var)
end
end
Module.get_formatted_playtime = function (x)
function Module.get_formatted_playtime(x)
if x < 5184000 then
local y = x / 216000
y = tostring(y)
@@ -114,7 +141,7 @@ Module.get_formatted_playtime = function (x)
end
end
Module.find_entities_by_last_user = function (player, surface, filters)
function Module.find_entities_by_last_user(player, surface, filters)
if type(player) == 'string' or not player then
error("bad argument #1 to '" .. debug.getinfo(1, 'n').name .. "' (number or LuaPlayer expected, got " .. type(player) .. ')', 1)
return
@@ -140,7 +167,7 @@ Module.find_entities_by_last_user = function (player, surface, filters)
return entities
end
Module.ternary = function (c, t, f)
function Module.ternary(c, t, f)
if c then
return t
else
@@ -152,7 +179,7 @@ local minutes_to_ticks = 60 * 60
local hours_to_ticks = 60 * 60 * 60
local ticks_to_minutes = 1 / minutes_to_ticks
local ticks_to_hours = 1 / hours_to_ticks
Module.format_time = function (ticks)
function Module.format_time(ticks)
local result = {}
local hours = math.floor(ticks * ticks_to_hours)
@@ -178,7 +205,7 @@ Module.format_time = function (ticks)
end
-- Convert date from 1999/01/01
Module.convert_date = function (year, month, day)
function Module.convert_date(year, month, day)
year = tonumber(year)
month = tonumber(month)
day = tonumber(day)
@@ -201,19 +228,4 @@ Module.convert_date = function (year, month, day)
return (day - 32075 + sub(1461 * (year + 4800 + d), 4) + sub(367 * (month - 2 - d * 12), 12) - sub(3 * sub(year + 4900 + d, 100), 4)) - 2415021
end
--- Compares positions
---@param position table
---@param area table
---@return boolean
function Module.inside(position, area)
if not position then
return false
end
local lt = area.left_top
local rb = area.right_bottom
return position.x >= lt.x and position.y >= lt.y and position.x <= rb.x and position.y <= rb.y
end
return Module