333 lines
8.9 KiB
Lua
333 lines
8.9 KiB
Lua
local util = {}
|
|
|
|
util.min = math.min
|
|
util.max = math.max
|
|
util.floor = math.floor
|
|
util.abs = math.abs
|
|
util.sqrt = math.sqrt
|
|
util.sin = math.sin
|
|
util.cos = math.cos
|
|
util.atan = math.atan
|
|
util.pi = math.pi
|
|
util.remove = table.remove
|
|
util.insert = table.insert
|
|
util.str_gsub = string.gsub
|
|
|
|
function util.send_message(text)
|
|
for _, player in pairs(game.players) do
|
|
player.print(text)
|
|
end
|
|
end
|
|
|
|
function util.remove_from_table(list, item)
|
|
local index = 0
|
|
for _,_item in ipairs(list) do
|
|
if item == _item then
|
|
index = _
|
|
break
|
|
end
|
|
end
|
|
if index > 0 then
|
|
util.remove(list, index)
|
|
end
|
|
end
|
|
|
|
function util.transfer_burner (entity_a, entity_b)
|
|
if entity_a.burner and entity_a.burner.currently_burning and entity_b.burner then
|
|
entity_b.burner.currently_burning = entity_a.burner.currently_burning.name
|
|
entity_b.burner.remaining_burning_fuel = entity_a.burner.remaining_burning_fuel
|
|
end
|
|
end
|
|
|
|
function util.transfer_inventory (entity_a, entity_b, inventory_type)
|
|
local inv_a = entity_a.get_inventory(inventory_type)
|
|
local inv_b = entity_b.get_inventory(inventory_type)
|
|
if inv_a and inv_b then
|
|
local contents = inv_a.get_contents()
|
|
for item_type, item_count in pairs(contents) do
|
|
inv_b.insert({name=item_type, count=item_count})
|
|
end
|
|
end
|
|
end
|
|
|
|
function util.transfer_inventory_filters (entity_a, entity_b, inventory_type)
|
|
local inv_a = entity_a.get_inventory(inventory_type)
|
|
local inv_b = entity_b.get_inventory(inventory_type)
|
|
if inv_a.supports_filters() and inv_b.supports_filters() then
|
|
for i = 1, util.min(#inv_a, #inv_b) do
|
|
local filter = inv_a.get_filter(i)
|
|
if filter then
|
|
inv_b.set_filter(i, filter)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function util.transfer_equipment_grid (entity_a, entity_b)
|
|
if not (entity_a.grid and entity_b.grid) then return end
|
|
local grid_a = entity_a.grid
|
|
local grid_b = entity_b.grid
|
|
local equipment = grid_a.equipment
|
|
for _, item in pairs(equipment) do
|
|
local new_item = grid_b.put({
|
|
name=item.name,
|
|
position=item.position})
|
|
if new_item then
|
|
if item.shield and item.shield > 0 then
|
|
new_item.shield = item.shield
|
|
end
|
|
if item.energy and item.energy > 0 then
|
|
new_item.energy = item.energy
|
|
end
|
|
else
|
|
util.send_message("Error transfering "..item.name)
|
|
end
|
|
end
|
|
end
|
|
|
|
function util.position_to_tile(position)
|
|
return {x = math.floor(position.x), y = math.floor(position.y)}
|
|
end
|
|
function util.tile_to_position(tile_position)
|
|
return {x = tile_position.x+0.5, y = tile_position.y+0.5}
|
|
end
|
|
|
|
function util.position_to_xy_string(position)
|
|
return util.xy_to_string(position.x, position.y)
|
|
end
|
|
|
|
function util.xy_to_string(x, y)
|
|
return util.floor(x) .. "_" .. util.floor(y)
|
|
end
|
|
|
|
function util.lerp_angles(a, b, alpha)
|
|
local da = b - a
|
|
|
|
if da < -0.5 then
|
|
da = da + 1
|
|
elseif da > 0.5 then
|
|
da = da - 1
|
|
end
|
|
local na = a + da * alpha
|
|
if na < 0 then
|
|
na = na + 1
|
|
elseif na > 1 then
|
|
na = na - 1
|
|
end
|
|
return na
|
|
end
|
|
|
|
function util.array_to_vector(array)
|
|
return {x = array[1], y = array[2]}
|
|
end
|
|
|
|
function util.vectors_delta(a, b)
|
|
return {x = b.x - a.x, y = b.y - a.y}
|
|
end
|
|
|
|
function util.vectors_delta_length(a, b)
|
|
return util.vector_length_xy(b.x - a.x, b.y - a.y)
|
|
end
|
|
|
|
function util.vector_length(a)
|
|
return util.sqrt(a.x * a.x + a.y * a.y)
|
|
end
|
|
|
|
function util.vector_length_xy(x, y)
|
|
return util.sqrt(x * x + y * y)
|
|
end
|
|
|
|
function util.vector_dot(a, b)
|
|
return a.x * b.x + a.y * b.y
|
|
end
|
|
|
|
function util.vector_dot_projection(a, b)
|
|
local n = util.vector_normalise(a)
|
|
local d = util.vector_dot(n, b)
|
|
return {x = n.x * d, y = n.y * d}
|
|
end
|
|
|
|
function util.vector_normalise(a)
|
|
local length = util.vector_length(a)
|
|
return {x = a.x/length, y = a.y/length}
|
|
end
|
|
|
|
function util.orientation_from_to(a, b)
|
|
return util.vector_to_orientation_xy(b.x - a.x, b.y - a.y)
|
|
end
|
|
|
|
function util.orientation_to_vector(orientation, length)
|
|
return {x = length * util.sin(orientation * 2 * util.pi), y = -length * util.cos(orientation * 2 * util.pi)}
|
|
end
|
|
|
|
function util.vectors_add(a, b)
|
|
return {x = a.x + b.x, y = a.y + b.y}
|
|
end
|
|
|
|
function util.lerp_vectors(a, b, alpha)
|
|
return {x = a.x + (b.x - a.x) * alpha, y = a.y + (b.y - a.y) * alpha}
|
|
end
|
|
|
|
function util.move_to(a, b, max_distance, eliptical)
|
|
-- move rfom a to b with max_distance.
|
|
-- if eliptical, reduce y change (i.e. turret muzzle flash offset)
|
|
local eliptical_scale = 0.9
|
|
local delta = util.vectors_delta(a, b)
|
|
if eliptical then
|
|
delta.y = delta.y / eliptical_scale
|
|
end
|
|
local length = util.vector_length(delta)
|
|
if (length > max_distance) then
|
|
local partial = max_distance / length
|
|
delta = {x = delta.x * partial, y = delta.y * partial}
|
|
end
|
|
if eliptical then
|
|
delta.y = delta.y * eliptical_scale
|
|
end
|
|
return {x = a.x + delta.x, y = a.y + delta.y}
|
|
end
|
|
|
|
function util.vector_to_orientation(v)
|
|
return util.vector_to_orientation_xy(v.x, v.y)
|
|
end
|
|
|
|
function util.vector_to_orientation_xy(x, y)
|
|
if x == 0 then
|
|
if y > 0 then
|
|
return 0.5
|
|
else
|
|
return 0
|
|
end
|
|
elseif y == 0 then
|
|
if x < 0 then
|
|
return 0.75
|
|
else
|
|
return 0.25
|
|
end
|
|
else
|
|
if y < 0 then
|
|
if x > 0 then
|
|
return util.atan(x / -y) / util.pi / 2
|
|
else
|
|
return 1 + util.atan(x / -y) / util.pi / 2
|
|
end
|
|
else
|
|
return 0.5 + util.atan(x / -y) / util.pi / 2
|
|
end
|
|
end
|
|
end
|
|
|
|
function util.direction_to_orientation(direction)
|
|
if direction == defines.direction.north then
|
|
return 0
|
|
elseif direction == defines.direction.northeast then
|
|
return 0.125
|
|
elseif direction == defines.direction.east then
|
|
return 0.25
|
|
elseif direction == defines.direction.southeast then
|
|
return 0.375
|
|
elseif direction == defines.direction.south then
|
|
return 0.5
|
|
elseif direction == defines.direction.southwest then
|
|
return 0.625
|
|
elseif direction == defines.direction.west then
|
|
return 0.75
|
|
elseif direction == defines.direction.northwest then
|
|
return 0.875
|
|
end
|
|
return 0
|
|
end
|
|
|
|
function util.signal_to_string(signal)
|
|
return signal.type .. "__" .. signal.name
|
|
end
|
|
|
|
function util.signal_container_add(container, signal, count)
|
|
if signal then
|
|
if not container[signal.type] then
|
|
container[signal.type] = {}
|
|
end
|
|
if container[signal.type][signal.name] then
|
|
container[signal.type][signal.name].count = container[signal.type][signal.name].count + count
|
|
else
|
|
container[signal.type][signal.name] = {signal = signal, count = count}
|
|
end
|
|
end
|
|
end
|
|
|
|
function util.signal_container_add_inventory(container, entity, inventory)
|
|
local inv = entity.get_inventory(inventory)
|
|
if inv then
|
|
local contents = inv.get_contents()
|
|
for item_type, item_count in pairs(contents) do
|
|
util.signal_container_add(container, {type="item", name=item_type}, item_count)
|
|
end
|
|
end
|
|
end
|
|
|
|
function util.signal_container_get(container, signal)
|
|
if container[signal.type] and container[signal.type][signal.name] then
|
|
return container[signal.type][signal.name]
|
|
end
|
|
end
|
|
|
|
util.char_to_multiplier = {
|
|
m = 0.001,
|
|
c = 0.01,
|
|
d = 0.1,
|
|
h = 100,
|
|
k = 1000,
|
|
M = 1000000,
|
|
G = 1000000000,
|
|
T = 1000000000000,
|
|
P = 1000000000000000,
|
|
}
|
|
|
|
function util.string_to_number(str)
|
|
str = ""..str
|
|
local number_string = ""
|
|
local last_char = nil
|
|
for i = 1, #str do
|
|
local c = str:sub(i,i)
|
|
if c == "." or tonumber(c) ~= nil then
|
|
number_string = number_string .. c
|
|
else
|
|
last_char = c
|
|
break
|
|
end
|
|
end
|
|
if last_char and util.char_to_multiplier[last_char] then
|
|
return tonumber(number_string) * util.char_to_multiplier[last_char]
|
|
end
|
|
return tonumber(number_string)
|
|
end
|
|
|
|
function util.replace(str, what, with)
|
|
what = util.str_gsub(what, "[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1") -- escape pattern
|
|
with = util.str_gsub(with, "[%%]", "%%%%") -- escape replacement
|
|
return util.str_gsub(str, what, with)
|
|
end
|
|
|
|
|
|
function util.replace_filenames_recursive(subject, what, with)
|
|
if subject.filename then
|
|
subject.filename = util.replace(subject.filename, what, with)
|
|
else
|
|
for _, sub in pairs(subject) do
|
|
if (type(sub) == "table") then
|
|
util.replace_filenames_recursive(sub, what, with)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function util.allow_productivity(recipe_name)
|
|
for _, prototype in pairs(data.raw["module"]) do
|
|
if prototype.limitation and string.find(prototype.name, "productivity", 1, true) then
|
|
table.insert(prototype.limitation, recipe_name)
|
|
end
|
|
end
|
|
end
|
|
|
|
return util
|