You've already forked ComfyFactorio
mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2026-04-28 21:04:39 +02:00
1976 lines
67 KiB
Lua
1976 lines
67 KiB
Lua
local Event = require 'utils.event'
|
|
local Color = require 'utils.color_presets'
|
|
local Global = require 'utils.global'
|
|
local Gui = require 'utils.gui'
|
|
local Task = require 'utils.task'
|
|
local Token = require 'utils.token'
|
|
local Commands = require 'utils.commands'
|
|
|
|
local this =
|
|
{
|
|
main_containers = {},
|
|
inf_gui = {},
|
|
saved_containers = {},
|
|
valid_storage =
|
|
{
|
|
['storage-tank'] = true
|
|
},
|
|
enabled = true,
|
|
editor = {},
|
|
disable_normal_placement = true,
|
|
debug = false,
|
|
cost_to_convert = 200
|
|
}
|
|
|
|
local default_limit = 50000
|
|
|
|
local converter_frame_for_player_name = Gui.uid_name()
|
|
local convert_to_infinite_container = Gui.uid_name()
|
|
local item_name_frame_name = Gui.uid_name()
|
|
local master_storage_btn_name = Gui.uid_name()
|
|
|
|
local toggle_render
|
|
|
|
local module_name = '[Infinity Storage] '
|
|
local insert = table.insert
|
|
local floor = math.floor
|
|
local pairs = pairs
|
|
local Public = {}
|
|
|
|
Global.register(
|
|
this,
|
|
function (tbl)
|
|
this = tbl
|
|
end
|
|
)
|
|
|
|
local remove_container
|
|
local refresh_main_frame
|
|
|
|
local delay_refresh_main_frame_task_token =
|
|
Token.register(
|
|
function (event)
|
|
local player_index = event.player_index
|
|
local player = game.get_player(player_index)
|
|
if not player or not player.valid then
|
|
return
|
|
end
|
|
|
|
local unit_number = event.unit_number
|
|
if not unit_number then
|
|
return
|
|
end
|
|
|
|
refresh_main_frame({ unit_number = unit_number, player = player })
|
|
end
|
|
)
|
|
|
|
function Public.get_table()
|
|
return this
|
|
end
|
|
|
|
local function draw_convert_button(parent, entity)
|
|
local frame = parent[converter_frame_for_player_name]
|
|
if frame and frame.valid then
|
|
Gui.destroy(frame)
|
|
end
|
|
|
|
local anchor =
|
|
{
|
|
gui = defines.relative_gui_type.storage_tank_gui,
|
|
position = defines.relative_gui_position.right
|
|
}
|
|
frame =
|
|
parent.add
|
|
{
|
|
type = 'frame',
|
|
name = converter_frame_for_player_name,
|
|
anchor = anchor,
|
|
direction = 'vertical'
|
|
}
|
|
|
|
local button =
|
|
frame.add
|
|
{
|
|
type = 'sprite-button',
|
|
sprite = 'item/' .. entity.name,
|
|
name = convert_to_infinite_container,
|
|
style = Gui.button_style,
|
|
tooltip = '[color=blue][Infinity storage][/color]\nYou can easily convert this container to an infinity storage.\n\nCosts ' .. this.cost_to_convert .. ' coins.'
|
|
}
|
|
Gui.set_data(button, entity)
|
|
end
|
|
|
|
local function validate()
|
|
if not this or not this.main_containers then
|
|
this =
|
|
{
|
|
main_containers = {},
|
|
inf_gui = {},
|
|
saved_containers = {},
|
|
valid_storage =
|
|
{
|
|
['storage-tank'] = true
|
|
},
|
|
enabled = true,
|
|
editor = {},
|
|
disable_normal_placement = true,
|
|
debug = false,
|
|
cost_to_convert = 200
|
|
}
|
|
end
|
|
end
|
|
|
|
local function has_value(tab)
|
|
local count = 0
|
|
for _, _ in pairs(tab) do
|
|
count = count + 1
|
|
end
|
|
return count
|
|
end
|
|
|
|
local function return_value(tab)
|
|
for index, value in pairs(tab) do
|
|
if value then
|
|
tab[index] = nil
|
|
return value, index
|
|
end
|
|
end
|
|
end
|
|
|
|
local function detect_item(container)
|
|
local fluidbox = container.entity.fluidbox
|
|
local fluid = fluidbox[1]
|
|
if fluid then
|
|
fluidbox.set_filter(1, { name = fluid.name, force = true })
|
|
container.item = fluid.name
|
|
container.temperature = fluid.temperature
|
|
return true, container.item
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function combine_tempatures(first_count, first_tempature, second_count, second_tempature)
|
|
if first_tempature == second_tempature then
|
|
return first_tempature
|
|
end
|
|
if first_tempature == nil then
|
|
return second_tempature
|
|
end
|
|
local total_count = first_count + second_count
|
|
return (first_tempature * first_count / total_count) + (second_tempature * second_count / total_count)
|
|
end
|
|
|
|
local function update_single_container(container)
|
|
local entity = container.entity
|
|
if not entity or not entity.valid then
|
|
return
|
|
end
|
|
|
|
if container.direction.state == 'none' then
|
|
return
|
|
end
|
|
|
|
if container.item == nil then
|
|
detect_item(container)
|
|
end
|
|
local item = container.item
|
|
if item == nil then
|
|
return
|
|
end
|
|
local capacity = container.capacity
|
|
local max_capacity = entity.fluidbox.get_capacity(1) * 0.5
|
|
if capacity > max_capacity then
|
|
container.capacity = max_capacity
|
|
capacity = max_capacity
|
|
end
|
|
|
|
local inventory_count = entity.get_fluid_count(item)
|
|
if inventory_count > capacity then
|
|
local amount_removed = entity.remove_fluid { name = item, amount = inventory_count - capacity }
|
|
container.temperature = combine_tempatures(container.count, container.temperature, amount_removed,
|
|
entity.fluidbox[1].temperature)
|
|
container.count = container.count + amount_removed
|
|
elseif inventory_count < capacity then
|
|
local to_add = capacity - inventory_count
|
|
if container.count < to_add then
|
|
to_add = container.count
|
|
end
|
|
if to_add ~= 0 then
|
|
local amount_added = entity.insert_fluid { name = item, amount = to_add, temperature = container.temperature }
|
|
container.count = container.count - amount_added
|
|
end
|
|
end
|
|
end
|
|
|
|
local function make_master_storage(player, source_container, destination_container)
|
|
local master, slave
|
|
if source_container.linked_to == destination_container.unit_number then
|
|
master = destination_container
|
|
slave = source_container
|
|
else
|
|
player.print('This storage is not linked to the destination storage (0).', Color.warning)
|
|
return
|
|
end
|
|
|
|
if not master or not slave then
|
|
player.print('This storage is not a valid storage (1).', Color.warning)
|
|
return
|
|
end
|
|
|
|
if master.mode ~= 1 or slave.mode ~= 3 then
|
|
player.print('This storage is not a valid storage (2).', Color.warning)
|
|
return
|
|
end
|
|
|
|
local links = master.links
|
|
if not links then
|
|
player.print('This storage is not linked to the destination storage (3).', Color.warning)
|
|
return
|
|
end
|
|
local slave_un = slave.unit_number
|
|
if not links[slave_un] and not links[tostring(slave_un)] then
|
|
player.print('This storage is not linked to the destination storage (4).', Color.warning)
|
|
return
|
|
end
|
|
|
|
local old_master_un = master.unit_number
|
|
local new_master_un = slave_un
|
|
|
|
local stored_count = master.count
|
|
master.count = 0
|
|
|
|
local new_links = {}
|
|
for unit, _ in pairs(links) do
|
|
local u = tonumber(unit) or unit
|
|
if u ~= new_master_un then
|
|
new_links[u] = true
|
|
end
|
|
end
|
|
new_links[old_master_un] = true
|
|
|
|
local share_name = master.share and master.share.name
|
|
|
|
master.links = nil
|
|
master.linked_to = new_master_un
|
|
master.mode = 3
|
|
master.requested_fluid = slave.requested_fluid
|
|
if master.share then
|
|
master.share.state = false
|
|
master.share.name = old_master_un
|
|
end
|
|
|
|
slave.linked_to = nil
|
|
slave.mode = 1
|
|
slave.requested_fluid = nil
|
|
slave.links = new_links
|
|
slave.limit = master.limit
|
|
slave.count = stored_count
|
|
if slave.share then
|
|
slave.share.state = true
|
|
if share_name ~= nil then
|
|
slave.share.name = share_name
|
|
end
|
|
end
|
|
|
|
for _, data in pairs(this.main_containers) do
|
|
if data and data.linked_to == old_master_un and data.unit_number ~= new_master_un then
|
|
data.linked_to = new_master_un
|
|
end
|
|
end
|
|
|
|
toggle_render(master)
|
|
toggle_render(slave)
|
|
end
|
|
|
|
local function validate_player(player)
|
|
if not player then
|
|
return false
|
|
end
|
|
if not player.valid then
|
|
return false
|
|
end
|
|
if not player.character then
|
|
return false
|
|
end
|
|
if not player.connected then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function does_exists(unit_number)
|
|
local containers = this.main_containers
|
|
if containers.index == 1 then
|
|
return false
|
|
end
|
|
|
|
if containers[unit_number] then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
local function add_object(unit_number, state)
|
|
local containers = this.main_containers
|
|
|
|
if not containers[unit_number] then
|
|
containers[unit_number] = state
|
|
end
|
|
return containers[unit_number]
|
|
end
|
|
|
|
local function remove_object(unit_number)
|
|
this.main_containers[unit_number] = nil
|
|
end
|
|
|
|
local function fetch_container(unit_number)
|
|
return this.main_containers[unit_number]
|
|
end
|
|
|
|
local function fetch_share(player, text)
|
|
local containers = this.main_containers
|
|
for unit_number, container in pairs(containers) do
|
|
if container.share.name == text and container.owner == player.force.index then
|
|
return true, unit_number
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
toggle_render = function (container)
|
|
if not container.entity or not container.entity.valid then
|
|
remove_container(container.unit_number)
|
|
return
|
|
end
|
|
|
|
if container.render then
|
|
container.render.destroy()
|
|
end
|
|
|
|
if container.share.state then
|
|
container.render =
|
|
rendering.draw_text
|
|
{
|
|
text = 'M',
|
|
surface = container.entity.surface,
|
|
target = container.entity,
|
|
target_offset = { 0, -0.6 },
|
|
scale = 2,
|
|
color = { r = 0, g = 0.6, b = 1 },
|
|
alignment = 'center'
|
|
}
|
|
elseif container.linked_to then
|
|
container.render =
|
|
rendering.draw_text
|
|
{
|
|
text = 'L',
|
|
surface = container.entity.surface,
|
|
target = container.entity,
|
|
target_offset = { 0, -0.6 },
|
|
scale = 2,
|
|
color = { r = 0, g = 0.6, b = 1 },
|
|
alignment = 'center'
|
|
}
|
|
else
|
|
container.render =
|
|
rendering.draw_text
|
|
{
|
|
text = '♾',
|
|
surface = container.entity.surface,
|
|
target = container.entity,
|
|
target_offset = { 0, -0.6 },
|
|
scale = 2,
|
|
color = { r = 0, g = 0.6, b = 1 },
|
|
alignment = 'center'
|
|
}
|
|
end
|
|
end
|
|
|
|
local function create_container(entity, stack, player)
|
|
entity.active = false
|
|
local unit_number = entity.unit_number
|
|
|
|
if not does_exists(unit_number) then
|
|
local container =
|
|
{
|
|
entity = entity,
|
|
capacity = 0.5 * entity.fluidbox.get_capacity(1),
|
|
count = 0,
|
|
owner = player.force.index,
|
|
unit_number = unit_number,
|
|
clear_fluid = { state = false },
|
|
limit = { state = true, number = default_limit },
|
|
direction =
|
|
{
|
|
state = 'import'
|
|
},
|
|
share =
|
|
{
|
|
state = false,
|
|
name = entity.unit_number
|
|
},
|
|
private = { state = true, owner = player.index },
|
|
mode = 1,
|
|
total_slots = 48
|
|
}
|
|
|
|
local tags = stack and stack.valid_for_read and stack.type == 'item-with-tags' and stack.tags
|
|
if tags and tags.name then
|
|
container.count = tags.count
|
|
container.temperature = tags.temperature
|
|
container.item = tags.name
|
|
entity.fluidbox.set_filter(1, { name = tags.name, force = true })
|
|
update_single_container(container)
|
|
end
|
|
local c = add_object(unit_number, container)
|
|
toggle_render(c)
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function get_share(entity, player)
|
|
local unit_number = entity.unit_number
|
|
local container = fetch_container(unit_number)
|
|
if not container.share then
|
|
create_container(entity, nil, player)
|
|
end
|
|
|
|
return container.share
|
|
end
|
|
|
|
local function restore_container(entity, player)
|
|
if this.saved_containers[player.index] and has_value(this.saved_containers[player.index]) >= 1 then
|
|
if not this.enabled then
|
|
goto continue
|
|
end
|
|
|
|
local container_index = this.saved_containers[player.index]
|
|
local container_to_place = return_value(container_index)
|
|
|
|
local container =
|
|
{
|
|
entity = entity,
|
|
owner = player.force.index,
|
|
capacity = container_to_place.capacity,
|
|
item = container_to_place.item,
|
|
count = container_to_place.count,
|
|
limit = container_to_place.limit,
|
|
unit_number = entity.unit_number,
|
|
clear_fluid = container_to_place.clear_fluid,
|
|
direction = container_to_place.direction,
|
|
share = container_to_place.share,
|
|
private = container_to_place.private,
|
|
mode = 1
|
|
}
|
|
|
|
local c = add_object(entity.unit_number, container)
|
|
toggle_render(c)
|
|
return true
|
|
end
|
|
::continue::
|
|
return false
|
|
end
|
|
|
|
local function remove_link(unit_number)
|
|
local container = fetch_container(unit_number)
|
|
if not container then
|
|
return
|
|
end
|
|
|
|
local links = container.links
|
|
-- container.share.name = default_share_name
|
|
container.share.state = false
|
|
if links then
|
|
for unit, _ in pairs(links) do
|
|
unit = tonumber(unit)
|
|
if unit then
|
|
local l_container = fetch_container(unit)
|
|
if l_container then
|
|
l_container.linked_to = nil
|
|
l_container.mode = 1
|
|
links[unit] = nil
|
|
toggle_render(l_container)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
remove_container = function (unit_number)
|
|
remove_link(unit_number)
|
|
remove_object(unit_number)
|
|
end
|
|
|
|
local function item_links(data)
|
|
local destination_direction = data.destination_container.direction
|
|
local destination_requested_fluid = data.destination_container.requested_fluid
|
|
|
|
if data.source_container.item == nil and data.destination_container.item ~= nil then
|
|
data.source_container.item = data.destination_container.item
|
|
end
|
|
|
|
if destination_direction.state == 'import' then -- import
|
|
if destination_requested_fluid then
|
|
if data.destination_container.item == destination_requested_fluid then
|
|
local source_item = data.source_container.item == destination_requested_fluid
|
|
if not source_item and destination_requested_fluid then
|
|
data.source_container.item = destination_requested_fluid
|
|
data.source_container.count = 0
|
|
end
|
|
|
|
local inventory_count = data.destination_container.entity.get_fluid_count(data.destination_container
|
|
.item)
|
|
if inventory_count then
|
|
local amount_removed = data.destination_container.entity.remove_fluid { name = data.destination_container.item, amount = inventory_count }
|
|
data.source_container.count = data.source_container.count + amount_removed
|
|
if data.source_container.item == nil then
|
|
data.source_container.item = destination_requested_fluid
|
|
end
|
|
end
|
|
end
|
|
else
|
|
local source_item = data.source_container.item == destination_requested_fluid
|
|
if not source_item and destination_requested_fluid then
|
|
data.source_container.item = destination_requested_fluid
|
|
data.source_container.count = 0
|
|
end
|
|
|
|
if not data.destination_container.entity or not data.destination_container.entity.valid then return end
|
|
|
|
if data.destination_container.item == nil then
|
|
-- detect_item(data.destination_container)
|
|
data.destination_container.item = data.source_container.item
|
|
end
|
|
|
|
local inventory_count = data.destination_container.entity.get_fluid_count(data.destination_container.item)
|
|
if inventory_count then
|
|
local amount_removed = data.destination_container.entity.remove_fluid { name = data.destination_container.item, amount = inventory_count }
|
|
data.source_container.count = data.source_container.count + amount_removed
|
|
end
|
|
end
|
|
else
|
|
if not prototypes.fluid[data.source_container.item] then
|
|
return
|
|
end
|
|
local item_stack = 10000
|
|
|
|
if not data.destination_container.item or data.destination_container.item ~= destination_requested_fluid then
|
|
data.destination_container.item = destination_requested_fluid
|
|
end
|
|
|
|
if not data.destination_container.temperature or data.destination_container.temperature ~= data.source_container.temperature then
|
|
data.destination_container.temperature = data.source_container.temperature
|
|
end
|
|
|
|
if destination_requested_fluid then
|
|
if data.source_container.item == destination_requested_fluid then
|
|
if data.source_container.count and data.source_container.count > 0 then
|
|
local dest_inventory_count = data.destination_container.entity.get_fluid_count(data
|
|
.destination_container.item)
|
|
if not dest_inventory_count or dest_inventory_count < (item_stack / 2) then
|
|
local to_insert = data.source_container.count
|
|
if to_insert > item_stack then
|
|
to_insert = floor(item_stack / 2)
|
|
elseif to_insert > 1 then
|
|
to_insert = floor(to_insert / 2)
|
|
end
|
|
|
|
if to_insert < 0 or to_insert == 0 then
|
|
return
|
|
end
|
|
|
|
local amount_added = data.destination_container.entity.insert_fluid { name = data.destination_container.item, amount = to_insert, temperature = data.destination_container.temperature }
|
|
data.source_container.count = data.source_container.count - amount_added
|
|
|
|
if data.source_container.count < 0 then
|
|
data.source_container.count = 0
|
|
data.source_container.item = nil
|
|
data.source_container.entity.clear_fluid_inside()
|
|
end
|
|
else
|
|
local dest_diff_remote_storage = data.source_container.count - data.destination_container.count
|
|
local dest_diff_local_storage = item_stack - data.destination_container.count
|
|
if dest_diff_remote_storage > 0 and dest_diff_local_storage > 0 and dest_diff_local_storage < item_stack then
|
|
if data.source_container.count >= dest_diff_local_storage then
|
|
local amount_added = data.destination_container.entity.insert_fluid { name = data.destination_container.item, amount = dest_diff_local_storage, temperature = data.destination_container.temperature }
|
|
data.source_container.count = data.source_container.count - amount_added
|
|
if data.source_container.count < 0 then
|
|
data.source_container.count = 0
|
|
data.source_container.item = nil
|
|
data.source_container.entity.clear_fluid_inside()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
if data.source_container.count > 0 then
|
|
local dest_inventory_count = data.destination_container.entity.get_fluid_count(data
|
|
.destination_container.item)
|
|
if not dest_inventory_count or dest_inventory_count == 0 then
|
|
local to_insert = 50
|
|
if to_insert > item_stack then
|
|
to_insert = floor(item_stack / 2)
|
|
elseif to_insert > 1 then
|
|
to_insert = floor(to_insert / 2)
|
|
end
|
|
|
|
if item_stack == 1 then
|
|
to_insert = 1
|
|
end
|
|
|
|
if data.destination_container.item == nil then
|
|
-- detect_item(data.destination_container)
|
|
data.destination_container.item = data.source_container.item
|
|
end
|
|
|
|
local amount_added = data.destination_container.entity.insert_fluid { name = data.destination_container.item, amount = to_insert, temperature = data.destination_container.temperature }
|
|
data.source_container.count = data.source_container.count - amount_added
|
|
|
|
if data.source_container.count < 0 then
|
|
data.source_container.count = 0
|
|
data.source_container.item = nil
|
|
data.source_container.entity.clear_fluid_inside()
|
|
end
|
|
else
|
|
if not data.destination_container.item then
|
|
detect_item(data.destination_container)
|
|
end
|
|
local dest_diff_remote_storage = data.source_container.count - data.destination_container.count
|
|
local dest_diff_local_storage = item_stack - data.destination_container.count
|
|
if dest_diff_remote_storage > 0 and dest_diff_local_storage > 0 and dest_diff_local_storage < item_stack then
|
|
if data.source_container.count >= dest_diff_local_storage then
|
|
local amount_added = data.destination_container.entity.insert_fluid { name = data.destination_container.item, amount = dest_diff_local_storage, temperature = data.destination_container.temperature }
|
|
data.source_container.count = data.source_container.count - amount_added
|
|
if data.source_container.count < 0 then
|
|
data.source_container.count = 0
|
|
data.source_container.item = nil
|
|
data.source_container.entity.clear_fluid_inside()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function refund_player(entity)
|
|
local unit_number = entity.unit_number
|
|
local container = fetch_container(unit_number)
|
|
if not container then
|
|
return
|
|
end
|
|
local player = game.get_player(container.private.owner)
|
|
|
|
if player and player.valid then
|
|
player.insert({ name = 'coin', count = this.cost_to_convert })
|
|
return
|
|
end
|
|
end
|
|
|
|
local function is_container_empty(entity, player)
|
|
local unit_number = entity.unit_number
|
|
local container = fetch_container(unit_number)
|
|
if not container then
|
|
return
|
|
end
|
|
|
|
local mode = container.mode
|
|
local fluids = container.item
|
|
if not fluids then
|
|
goto no_storage
|
|
end
|
|
if mode == 2 then
|
|
if container.count >= 1000 then
|
|
if not this.saved_containers[player.index] then
|
|
this.saved_containers[player.index] = {}
|
|
end
|
|
container.entity = nil
|
|
|
|
this.saved_containers[player.index][unit_number] = container
|
|
end
|
|
end
|
|
::no_storage::
|
|
|
|
remove_container(unit_number)
|
|
end
|
|
|
|
local function on_entity_died(event)
|
|
local entity = event.entity
|
|
if not entity then
|
|
return
|
|
end
|
|
if not this.valid_storage[entity.type] then
|
|
return
|
|
end
|
|
|
|
local unit_number = entity.unit_number
|
|
remove_container(unit_number)
|
|
end
|
|
|
|
local function check_limit_on_source_and_content_on_destination(data)
|
|
local source_links = data.source_container.links
|
|
if source_links then
|
|
if data.source_container and data.source_container.count and data.source_container.limit and data.source_container.limit.number and data.destination_container.mode ~= 1 then
|
|
if data.source_container.limit.state and data.source_container.count > data.source_container.limit.number and data.destination_container.direction.state == 'import' then
|
|
data.destination_container.direction.previous = data.destination_container.direction.state
|
|
data.destination_container.direction.state = 'none'
|
|
elseif data.source_container.limit.state then
|
|
if data.source_container.count < data.source_container.limit.number and data.destination_container.direction.state == 'none' then
|
|
data.destination_container.direction.state = data.destination_container.direction.previous
|
|
end
|
|
elseif data.destination_container.direction.previous then
|
|
data.destination_container.direction.state = data.destination_container.direction.previous
|
|
data.destination_container.direction.previous = nil
|
|
end
|
|
else
|
|
if not data.source_container.limit then
|
|
data.source_container.limit = { state = true, number = default_limit }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function on_pre_player_mined_item(event)
|
|
local entity = event.entity
|
|
local player = game.get_player(event.player_index)
|
|
if not player then
|
|
return
|
|
end
|
|
if not this.valid_storage[entity.type] then
|
|
return
|
|
end
|
|
refund_player(entity)
|
|
is_container_empty(entity, player)
|
|
local data = this.inf_gui[player.name]
|
|
if not data then
|
|
return
|
|
end
|
|
data.frame.destroy()
|
|
end
|
|
|
|
local function get_link(data)
|
|
if data.destination_container and data.destination_container.linked_to then
|
|
local linked_to = tonumber(data.destination_container.linked_to)
|
|
if not linked_to then
|
|
return false
|
|
end
|
|
local source_container = fetch_container(linked_to)
|
|
if not source_container then
|
|
remove_container(linked_to)
|
|
return false
|
|
end
|
|
|
|
data.source_container = source_container
|
|
end
|
|
end
|
|
|
|
local function check_links(data)
|
|
get_link(data)
|
|
|
|
if data.source_container then
|
|
check_limit_on_source_and_content_on_destination(data)
|
|
item_links(data)
|
|
end
|
|
end
|
|
|
|
local function check_mode_on_container(data)
|
|
local container = data.container.entity
|
|
local mode = data.container.mode
|
|
|
|
if mode == 1 then
|
|
container.destructible = false
|
|
container.minable = false
|
|
elseif mode == 2 then
|
|
container.destructible = true
|
|
container.minable = true
|
|
elseif mode == 3 then
|
|
container.destructible = false
|
|
container.minable = false
|
|
end
|
|
end
|
|
|
|
local function update_container(fluid_prototypes)
|
|
local containers = this.main_containers
|
|
for unit_number, container in next, containers do
|
|
if container and not container.entity.valid then
|
|
remove_container(unit_number)
|
|
goto continue
|
|
end
|
|
|
|
local inv = container.content
|
|
check_mode_on_container({ container = container, count = 0, inv = inv })
|
|
check_links({ destination_container = container, inv = inv, fluid_prototypes = fluid_prototypes })
|
|
|
|
update_single_container(container)
|
|
|
|
::continue::
|
|
end
|
|
end
|
|
|
|
local function text_changed(event)
|
|
local element = event.element
|
|
if not element then
|
|
return
|
|
end
|
|
if not element.valid then
|
|
return
|
|
end
|
|
|
|
local player = game.get_player(event.player_index)
|
|
|
|
local data = this.inf_gui[player.name]
|
|
if not data then
|
|
return
|
|
end
|
|
|
|
local name = element.name
|
|
|
|
local entity = data.entity
|
|
if not entity or not entity.valid then
|
|
return
|
|
end
|
|
|
|
if string.len(element.text) > 50 then
|
|
element.text = ''
|
|
end
|
|
|
|
local unit_number = entity.unit_number
|
|
local container = fetch_container(unit_number)
|
|
|
|
if name and name == 'share_name' and element.text then
|
|
if string.len(element.text) > 2 then
|
|
if not fetch_share(player, element.text) then
|
|
container.share.name = element.text
|
|
else
|
|
player.print(module_name .. 'A share with name "' .. element.text .. '" already exists.', Color.fail)
|
|
end
|
|
end
|
|
end
|
|
|
|
local value = tonumber(element.text)
|
|
|
|
if not value then
|
|
this.inf_gui[player.name].updated = false
|
|
return
|
|
end
|
|
|
|
if value ~= '' then
|
|
if name and name == 'limit_number' then
|
|
if value >= 1 then
|
|
data.text_field.text = tostring(value)
|
|
container.limit.number = value
|
|
elseif value <= default_limit then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
this.inf_gui[player.name].updated = false
|
|
end
|
|
|
|
--- Iterates over player containers.
|
|
---@param index any
|
|
---@param unit_number any
|
|
---@return table
|
|
local function get_owner_containers(index, unit_number)
|
|
local t = {}
|
|
local containers = this.main_containers
|
|
for check_unit_number, container in pairs(containers) do
|
|
if container.owner == index then
|
|
if container.entity and container.entity.valid then
|
|
if check_unit_number ~= unit_number and container.share.state then
|
|
insert(t, container)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
|
|
refresh_main_frame = function (data)
|
|
local player = data.player
|
|
local unit_number = data.unit_number
|
|
|
|
local container = fetch_container(unit_number)
|
|
local entity = container.entity
|
|
if not entity or not entity.valid then
|
|
return
|
|
end
|
|
|
|
local player_gui = this.inf_gui[player.name]
|
|
local volatile_tbl = player_gui.volatile_tbl
|
|
|
|
volatile_tbl.clear()
|
|
|
|
local mode = container.mode
|
|
|
|
if mode ~= 1 then
|
|
if mode ~= 4 then
|
|
remove_link(unit_number)
|
|
end
|
|
end
|
|
|
|
if mode ~= 3 then
|
|
if container and container.linked_to then
|
|
container.linked_to = nil
|
|
end
|
|
end
|
|
|
|
if mode == 1 then
|
|
local limit_tooltip = '[color=yellow]Limit Info:[/color]\nThis will stop the input after the limit is reached.'
|
|
local clear_tooltip = '[color=yellow]Info:[/color]\nThis will clear all fluids.'
|
|
local share_tooltip =
|
|
'[color=yellow]Share Info:[/color]\nA name for the share so you can easy find it when you want to link it with another container.'
|
|
|
|
local primary_tbl = volatile_tbl.add { type = 'table', column_count = 8, name = 'primary_tbl' }
|
|
|
|
local limit_one_label = primary_tbl.add({ type = 'label', caption = 'Limit Enabled: ', tooltip = limit_tooltip })
|
|
limit_one_label.style.font = 'heading-2'
|
|
local limit_one_checkbox = primary_tbl.add(
|
|
{
|
|
type = 'checkbox',
|
|
name = 'limit_storage',
|
|
state = container.limit
|
|
.state
|
|
})
|
|
limit_one_checkbox.tooltip = limit_tooltip
|
|
limit_one_checkbox.style.minimal_height = 25
|
|
limit_one_checkbox.style.minimal_width = 25
|
|
|
|
local bottom_flow = primary_tbl.add { type = 'flow' }
|
|
bottom_flow.style.minimal_width = 40
|
|
|
|
local limit_two_label = bottom_flow.add({ type = 'label', caption = 'Limit: ', tooltip = limit_tooltip })
|
|
limit_two_label.style.font = 'heading-2'
|
|
local limit_two_text = bottom_flow.add(
|
|
{
|
|
type = 'textfield',
|
|
name = 'limit_number',
|
|
text = container.limit
|
|
.number,
|
|
})
|
|
limit_two_text.style.width = 80
|
|
limit_two_text.numeric = true
|
|
limit_two_text.tooltip = limit_tooltip
|
|
limit_two_text.style.minimal_width = 25
|
|
|
|
this.inf_gui[player.name].text_field = limit_two_text
|
|
this.inf_gui[player.name].limited = limit_one_checkbox
|
|
|
|
local private_tooltip =
|
|
'[color=yellow]Private Info:[/color]\nThis will make it so no one else other than you can open this container.'
|
|
|
|
|
|
|
|
local clear_tbl = volatile_tbl.add { type = 'table', column_count = 8, name = 'clear_tbl' }
|
|
|
|
local clear_one_label = clear_tbl.add({ type = 'label', caption = 'Clear fluids: ', tooltip = clear_tooltip })
|
|
clear_one_label.style.font = 'heading-2'
|
|
local clear_checkbox = clear_tbl.add(
|
|
{
|
|
type = 'checkbox',
|
|
name = 'clear_checkbox',
|
|
state = container
|
|
.clear_fluid.state
|
|
})
|
|
clear_checkbox.tooltip = clear_tooltip
|
|
clear_checkbox.style.minimal_height = 25
|
|
clear_checkbox.style.minimal_width = 25
|
|
if not container.item then
|
|
clear_checkbox.enabled = false
|
|
clear_checkbox.tooltip = 'No fluids to clear.'
|
|
end
|
|
|
|
local private_label = clear_tbl.add(
|
|
{
|
|
type = 'label',
|
|
caption = 'Private container? ',
|
|
tooltip =
|
|
private_tooltip
|
|
})
|
|
private_label.style.font = 'heading-2'
|
|
local private_checkbox = clear_tbl.add(
|
|
{
|
|
type = 'checkbox',
|
|
name = 'private_container',
|
|
state = container
|
|
.private.state
|
|
})
|
|
private_checkbox.tooltip = private_tooltip
|
|
private_checkbox.style.minimal_height = 25
|
|
|
|
local share_tbl = volatile_tbl.add { type = 'table', column_count = 8, name = 'share_tbl' }
|
|
|
|
local share_one_label = share_tbl.add({ type = 'label', caption = 'Share Enabled: ', tooltip = share_tooltip })
|
|
share_one_label.style.font = 'heading-2'
|
|
local share_one_checkbox = share_tbl.add(
|
|
{
|
|
type = 'checkbox',
|
|
name = 'share_container',
|
|
state = get_share(entity,
|
|
player).state
|
|
})
|
|
share_one_checkbox.tooltip = share_tooltip
|
|
share_one_checkbox.style.minimal_height = 25
|
|
share_one_checkbox.style.minimal_width = 25
|
|
|
|
local share_one_bottom_flow = share_tbl.add { type = 'flow' }
|
|
share_one_bottom_flow.style.minimal_width = 40
|
|
|
|
local share_two_label = share_one_bottom_flow.add(
|
|
{
|
|
type = 'label',
|
|
caption = 'Share Name: ',
|
|
tooltip =
|
|
share_tooltip
|
|
})
|
|
share_two_label.style.font = 'heading-2'
|
|
local share_two_text = share_one_bottom_flow.add(
|
|
{
|
|
type = 'textfield',
|
|
name = 'share_name',
|
|
text = get_share(
|
|
entity, player).name
|
|
})
|
|
share_two_text.style.width = 150
|
|
share_two_text.allow_decimal = true
|
|
share_two_text.allow_negative = false
|
|
share_two_text.tooltip = share_tooltip
|
|
share_two_text.style.minimal_width = 25
|
|
elseif mode == 3 then
|
|
local linker_tooltip =
|
|
'[color=yellow]Link Info:[/color]\nThis will only work with containers that you have placed.'
|
|
local directions_tooltip =
|
|
'[color=yellow]Direction Info:[/color]\nChoose whether to import the item(s) to the main storage or export the item(s) from the main storage.'
|
|
|
|
local linker = volatile_tbl.add { type = 'table', column_count = 8, name = 'linker' }
|
|
if container then
|
|
if container and container.owner ~= player.force.index then
|
|
local link_label = linker.add(
|
|
{
|
|
type = 'label',
|
|
caption = 'Not owner of container. ',
|
|
tooltip =
|
|
linker_tooltip
|
|
})
|
|
link_label.style.font = 'heading-2'
|
|
else
|
|
local directions_tbl = volatile_tbl.add { type = 'table', column_count = 8, name = 'directions_tbl' }
|
|
local state
|
|
if container.direction and container.direction.state then
|
|
state = container.direction.state
|
|
else
|
|
state = 'export'
|
|
end
|
|
local directions_switch =
|
|
directions_tbl.add(
|
|
{
|
|
type = 'switch',
|
|
name = 'directions_container',
|
|
allow_none_state = false,
|
|
switch_state = state == 'import' and 'left' or 'right',
|
|
left_label_caption = 'Import',
|
|
right_label_caption = 'Export'
|
|
}
|
|
)
|
|
directions_switch.tooltip = directions_tooltip
|
|
|
|
this.inf_gui[player.name].directions = directions_switch
|
|
local sublinker = volatile_tbl.add { type = 'table', column_count = 1, name = 'sublinker' }
|
|
local itemdesc = volatile_tbl.add { type = 'table', column_count = 2, name = 'itemdesc' }
|
|
local containers = get_owner_containers(container.owner, unit_number)
|
|
local linked_container = fetch_container(container.linked_to)
|
|
|
|
if not next(containers) then
|
|
local link_label = sublinker.add({ type = 'label', caption = 'No containers found.' })
|
|
link_label.style.font = 'heading-2'
|
|
return
|
|
end
|
|
|
|
if container.linked_to and linked_container then
|
|
if container.requested_fluid then
|
|
local localized_name = prototypes.fluid[container.requested_fluid].localised_name
|
|
local link_label = sublinker.add(
|
|
{
|
|
type = 'label',
|
|
caption = 'Linked with: [color=yellow]' ..
|
|
linked_container.share.name .. '[/color]',
|
|
tooltip = linker_tooltip
|
|
})
|
|
link_label.style.font = 'heading-2'
|
|
link_label = itemdesc.add(
|
|
{
|
|
type = 'label',
|
|
caption = 'Linked item:',
|
|
tooltip =
|
|
linker_tooltip
|
|
})
|
|
link_label.style.font = 'heading-2'
|
|
link_label = itemdesc.add(
|
|
{
|
|
type = 'label',
|
|
caption = localized_name,
|
|
tooltip =
|
|
linker_tooltip
|
|
})
|
|
link_label.style.font_color = Color.green
|
|
link_label.style.font = 'heading-2'
|
|
else
|
|
local link_label = sublinker.add(
|
|
{
|
|
type = 'label',
|
|
caption = 'Linked with: [color=yellow]' ..
|
|
linked_container.share.name .. '[/color]',
|
|
tooltip = linker_tooltip
|
|
})
|
|
link_label.style.font = 'heading-2'
|
|
end
|
|
else
|
|
local link_item_label = sublinker.add(
|
|
{
|
|
type = 'label',
|
|
caption = 'Link with specific item:\n',
|
|
tooltip =
|
|
linker_tooltip
|
|
})
|
|
link_item_label.style.font = 'heading-2'
|
|
|
|
local item_scroll_pane =
|
|
sublinker.add
|
|
{
|
|
type = 'scroll-pane',
|
|
vertical_scroll_policy = 'auto',
|
|
horizontal_scroll_policy = 'never'
|
|
}
|
|
local item_scroll_style = item_scroll_pane.style
|
|
item_scroll_style.maximal_height = 150
|
|
item_scroll_style.vertically_squashable = true
|
|
item_scroll_style.bottom_padding = 2
|
|
item_scroll_style.left_padding = 2
|
|
item_scroll_style.right_padding = 2
|
|
item_scroll_style.top_padding = 2
|
|
local itemlinker = item_scroll_pane.add { type = 'table', column_count = 8, name = 'itemlinker' }
|
|
|
|
for i = 1, #containers do
|
|
if containers then
|
|
local container_chest = containers[i]
|
|
if type(container_chest) ~= 'string' then
|
|
if container_chest.item then
|
|
local localized_name = prototypes.fluid[container_chest.item].localised_name
|
|
|
|
local flowlinker = itemlinker.add { type = 'flow' }
|
|
local container_item =
|
|
flowlinker.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = item_name_frame_name,
|
|
style = 'slot_button',
|
|
sprite = 'fluid/' .. container_chest.item,
|
|
tooltip = { '', localized_name, '\n', container_chest.share.name, '\n', container_chest.count }
|
|
}
|
|
Gui.set_data(container_item,
|
|
{ name = container_chest.item, unit_number = unit_number, share = container_chest.share.name })
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- if directions_switch.switch_state == 'import' then
|
|
sublinker.add({ type = 'line' })
|
|
local link_container_label = sublinker.add(
|
|
{
|
|
type = 'label',
|
|
caption = 'Link with container:\n',
|
|
tooltip =
|
|
linker_tooltip
|
|
})
|
|
link_container_label.style.font = 'heading-2'
|
|
local container_scroll_pane =
|
|
sublinker.add
|
|
{
|
|
type = 'scroll-pane',
|
|
vertical_scroll_policy = 'auto',
|
|
horizontal_scroll_policy = 'never'
|
|
}
|
|
local container_scroll_style = container_scroll_pane.style
|
|
container_scroll_style.maximal_height = 150
|
|
container_scroll_style.vertically_squashable = true
|
|
container_scroll_style.bottom_padding = 2
|
|
container_scroll_style.left_padding = 2
|
|
container_scroll_style.right_padding = 2
|
|
container_scroll_style.top_padding = 2
|
|
local containerlinker = container_scroll_pane.add { type = 'table', column_count = 8, name = 'containerlinker' }
|
|
|
|
for i = 1, #containers do
|
|
if containers then
|
|
local container_chest = containers[i]
|
|
if type(container_chest) ~= 'string' then
|
|
local flowlinker = containerlinker.add { type = 'flow' }
|
|
local containeritem = flowlinker.add { type = 'sprite-button', name = item_name_frame_name, style = 'slot_button', sprite = 'item/' .. container_chest.entity.name, tooltip = 'Container share name: ' .. container_chest.share.name }
|
|
Gui.set_data(containeritem,
|
|
{ name = nil, unit_number = unit_number, share = container_chest.share.name })
|
|
end
|
|
-- end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function gui_opened(event)
|
|
if not event.gui_type == defines.gui_type.entity then
|
|
return
|
|
end
|
|
local entity = event.entity
|
|
if not (entity and entity.valid) then
|
|
return
|
|
end
|
|
if not this.valid_storage[entity.type] then
|
|
return
|
|
end
|
|
local unit_number = entity.unit_number
|
|
local player = game.get_player(event.player_index)
|
|
|
|
local container = fetch_container(unit_number)
|
|
if not container then
|
|
return
|
|
end
|
|
|
|
if container.private.state then
|
|
if player.index ~= container.private.owner and not player.admin then
|
|
player.opened = nil
|
|
return
|
|
end
|
|
end
|
|
|
|
local frame = player.gui.center[tostring(unit_number)]
|
|
if not frame or not frame.valid then
|
|
frame =
|
|
player.gui.center.add
|
|
{
|
|
type = 'frame',
|
|
caption = 'Unlimited Storage',
|
|
direction = 'vertical',
|
|
name = tostring(unit_number)
|
|
}
|
|
end
|
|
|
|
local controls = frame.add { type = 'flow', direction = 'horizontal' }
|
|
local controls2 = frame.add { type = 'flow', direction = 'horizontal' }
|
|
local fluids = frame.add { type = 'flow', direction = 'vertical' }
|
|
|
|
local mode = container.mode
|
|
local selected = mode and mode or 1
|
|
local controltbl = controls.add { type = 'table', column_count = 1 }
|
|
local btntbl = controltbl.add { type = 'table', column_count = 2 }
|
|
local modetbl = controltbl.add { type = 'table', column_count = 2 }
|
|
local volatile_tbl = controls2.add { type = 'table', column_count = 1 }
|
|
|
|
local mode_tooltip =
|
|
'[color=yellow]Mode Info:[/color]\nEnabled: will active the container and allow for insertions.\nDisabled: will deactivate the container and let´s the player utilize the GUI to retrieve fluids.\nLink: Link a container with another container. Content is divided between them.'
|
|
|
|
local btn =
|
|
btntbl.add
|
|
{
|
|
type = 'sprite-button',
|
|
tooltip = '[color=blue]Info![/color]\nContainer ID: ' .. unit_number .. '\nThis container stores unlimited quantity of a fluid',
|
|
sprite = Gui.info_icon
|
|
}
|
|
btn.style.height = 20
|
|
btn.style.width = 20
|
|
btn.enabled = false
|
|
btn.focus()
|
|
|
|
local mode_label = modetbl.add { type = 'label', caption = 'Mode: ', tooltip = mode_tooltip }
|
|
mode_label.style.font = 'heading-2'
|
|
local drop_down_fluids
|
|
|
|
if player.admin and (this.editor[player.name]) then
|
|
drop_down_fluids = { 'Enabled', 'Disabled', 'Link', 'Editor' }
|
|
else
|
|
drop_down_fluids = { 'Enabled', 'Disabled', 'Link' }
|
|
end
|
|
|
|
if container.mode == 3 and container.linked_to then
|
|
local master_storage_btn =
|
|
btntbl.add
|
|
{
|
|
type = 'sprite-button',
|
|
name = master_storage_btn_name,
|
|
tooltip = 'Click to make this storage a master storage.',
|
|
sprite = 'utility/bookmark'
|
|
}
|
|
master_storage_btn.style.height = 20
|
|
master_storage_btn.style.width = 20
|
|
master_storage_btn.enabled = true
|
|
end
|
|
|
|
local drop_down =
|
|
modetbl.add
|
|
{
|
|
type = 'drop-down',
|
|
items = drop_down_fluids,
|
|
selected_index = selected,
|
|
name = unit_number,
|
|
tooltip = mode_tooltip
|
|
}
|
|
|
|
this.inf_gui[player.name] =
|
|
{
|
|
fluid_frame = fluids,
|
|
frame = frame,
|
|
volatile_tbl = volatile_tbl,
|
|
drop_down = drop_down,
|
|
entity = entity,
|
|
updated = false
|
|
}
|
|
|
|
container.mode = drop_down.selected_index
|
|
player.opened = frame
|
|
|
|
refresh_main_frame({ unit_number = unit_number, player = player })
|
|
end
|
|
|
|
local function on_built_entity(event, raised)
|
|
if this.disable_normal_placement and not raised then
|
|
return
|
|
end
|
|
local entity = event.entity
|
|
local stack = event.stack
|
|
if not entity.valid then
|
|
return
|
|
end
|
|
if not this.valid_storage[entity.type] then
|
|
return
|
|
end
|
|
if event.player_index then
|
|
local player = game.get_player(event.player_index)
|
|
local c = restore_container(entity, player)
|
|
if c then
|
|
gui_opened(event)
|
|
end
|
|
|
|
local s = create_container(entity, stack, player)
|
|
if s then
|
|
gui_opened(event)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function update_gui()
|
|
for _, player in pairs(game.connected_players) do
|
|
local container_gui_data = this.inf_gui[player.name]
|
|
if not container_gui_data then
|
|
goto continue
|
|
end
|
|
local frame = container_gui_data.fluid_frame
|
|
local entity = container_gui_data.entity
|
|
if not frame then
|
|
goto continue
|
|
end
|
|
if not entity or not entity.valid then
|
|
goto continue
|
|
end
|
|
|
|
local unit_number = entity.unit_number
|
|
local container = fetch_container(unit_number)
|
|
|
|
local mode = container.mode
|
|
if (mode == 2 or mode == 4) and this.inf_gui[player.name].updated then
|
|
goto continue
|
|
end
|
|
if not frame or not frame.valid then
|
|
goto continue
|
|
end
|
|
|
|
frame.clear()
|
|
|
|
local tbl = frame.add { type = 'table', column_count = 10, name = 'infinity_storage_inventory' }
|
|
|
|
if not container.item or not container.count then
|
|
if mode == 1 or mode == 2 then
|
|
local no_fluid = tbl.add { type = 'sprite-button', style = 'slot_button' }
|
|
no_fluid.enabled = false
|
|
elseif mode == 4 then
|
|
local no_fluid = tbl.add { type = 'choose-elem-button', style = 'slot_button', elem_type = 'fluid' }
|
|
no_fluid.enabled = true
|
|
end
|
|
this.inf_gui[player.name].updated = true
|
|
goto continue
|
|
end
|
|
|
|
local btn
|
|
if container.requested_fluid then
|
|
local localized_name = prototypes.fluid[container.requested_fluid].localised_name
|
|
local flow = tbl.add { type = 'flow' }
|
|
flow.style.horizontally_stretchable = true
|
|
btn =
|
|
flow.add
|
|
{
|
|
type = 'sprite-button',
|
|
sprite = 'fluid/' .. container.requested_fluid,
|
|
style = 'slot_button',
|
|
name = container.requested_fluid,
|
|
tooltip = localized_name
|
|
}
|
|
btn.enabled = false
|
|
end
|
|
|
|
local inventory_count = entity.get_fluid_count(container.item)
|
|
local total_fluid_count = inventory_count + container.count
|
|
|
|
if mode == 1 or mode == 3 then
|
|
local localized_name = prototypes.fluid[container.item].localised_name
|
|
if container.requested_fluid and tbl[container.requested_fluid] then
|
|
tbl[container.requested_fluid].number = total_fluid_count
|
|
else
|
|
btn =
|
|
tbl.add
|
|
{
|
|
type = 'sprite-button',
|
|
sprite = 'fluid/' .. container.item,
|
|
style = 'slot_button',
|
|
number = total_fluid_count,
|
|
name = container.item,
|
|
tooltip = localized_name
|
|
}
|
|
btn.enabled = false
|
|
end
|
|
elseif mode == 2 or mode == 4 then
|
|
local localized_name = prototypes.fluid[container.item].localised_name
|
|
btn =
|
|
tbl.add
|
|
{
|
|
type = 'sprite-button',
|
|
sprite = 'fluid/' .. container.item,
|
|
tooltip = localized_name,
|
|
style = 'slot_button',
|
|
number = total_fluid_count,
|
|
name = container.item
|
|
}
|
|
btn.enabled = true
|
|
end
|
|
|
|
this.inf_gui[player.name].updated = true
|
|
::continue::
|
|
end
|
|
end
|
|
|
|
local function gui_closed(event)
|
|
local player = game.get_player(event.player_index)
|
|
local type = event.gui_type
|
|
|
|
if type == defines.gui_type.custom then
|
|
local data = this.inf_gui[player.name]
|
|
if not data then
|
|
return
|
|
end
|
|
data.frame.destroy()
|
|
this.inf_gui[player.name] = nil
|
|
end
|
|
end
|
|
|
|
local function state_changed(event)
|
|
local player = game.get_player(event.player_index)
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
|
|
local element = event.element
|
|
if not element.valid then
|
|
return
|
|
end
|
|
if not element.selected_index then
|
|
return
|
|
end
|
|
local name = element.name
|
|
|
|
if name == 'linker' then
|
|
local fluids = element.fluids
|
|
if not fluids then
|
|
return
|
|
end
|
|
local selected = fluids[element.selected_index]
|
|
if not selected then
|
|
return
|
|
end
|
|
if element.selected_index == 1 then
|
|
return
|
|
end
|
|
local unit_number = this.inf_gui[player.name] and this.inf_gui[player.name].entity and
|
|
this.inf_gui[player.name].entity.unit_number
|
|
local container = fetch_container(unit_number)
|
|
if container then
|
|
local _, _unit_number = fetch_share(player, selected)
|
|
if _unit_number then
|
|
container.linked_to = _unit_number
|
|
local linked_container = fetch_container(_unit_number)
|
|
if linked_container then
|
|
if not linked_container.links then
|
|
linked_container.links = {}
|
|
end
|
|
if not linked_container.links[unit_number] then
|
|
linked_container.links[unit_number] = true
|
|
end
|
|
end
|
|
else
|
|
container.linked_to = selected
|
|
end
|
|
this.inf_gui[player.name].updated = false
|
|
toggle_render(container)
|
|
refresh_main_frame({ unit_number = unit_number, player = player })
|
|
return
|
|
end
|
|
end
|
|
|
|
local unit_number = tonumber(element.name)
|
|
if unit_number then
|
|
local container = fetch_container(unit_number)
|
|
if not container or not container.mode then
|
|
return
|
|
end
|
|
container.mode = element.selected_index
|
|
local mode = container.mode
|
|
|
|
refresh_main_frame({ unit_number = unit_number, player = player })
|
|
|
|
toggle_render(container)
|
|
|
|
if mode >= 2 then
|
|
this.inf_gui[player.name].updated = false
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.remove_player(index)
|
|
local containers = this.main_containers
|
|
if next(containers) then
|
|
for unit_number, container in pairs(containers) do
|
|
if container.private.owner == index then
|
|
if container.entity and container.entity.valid then
|
|
container.entity.destroy()
|
|
end
|
|
remove_container(unit_number)
|
|
end
|
|
end
|
|
end
|
|
|
|
this.saved_containers[index] = nil
|
|
end
|
|
|
|
local function gui_click(event)
|
|
local element = event.element
|
|
local player = game.get_player(event.player_index)
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
if not element.valid then
|
|
return
|
|
end
|
|
if element.name == 'directions_container' then
|
|
local pGui = this.inf_gui[player.name]
|
|
if not pGui then
|
|
return
|
|
end
|
|
|
|
local entity = pGui.entity
|
|
if not (entity and entity.valid) then
|
|
return
|
|
end
|
|
local unit_number = entity.unit_number
|
|
local container = fetch_container(unit_number)
|
|
container.direction.state = element.switch_state
|
|
this.inf_gui[player.name].updated = false
|
|
return
|
|
end
|
|
|
|
local parent = element.parent
|
|
if not parent then
|
|
return
|
|
end
|
|
if parent.name ~= 'infinity_storage_inventory' then
|
|
return
|
|
end
|
|
local unit_number = tonumber(parent.parent.parent.name)
|
|
if tonumber(element.name) == unit_number then
|
|
return
|
|
end
|
|
|
|
local shift = event.shift
|
|
local ctrl = event.control
|
|
local container = fetch_container(unit_number)
|
|
local mode = container.mode
|
|
|
|
if not container.item then
|
|
return
|
|
end
|
|
|
|
if player.admin then
|
|
if mode == 4 then
|
|
if ctrl then
|
|
container.count = container.count + 500000
|
|
goto update
|
|
elseif shift then
|
|
container.count = container.count - 500000
|
|
if container.count <= 0 then
|
|
container.item = nil
|
|
container.count = 0
|
|
container.entity.clear_fluid_inside()
|
|
end
|
|
goto update
|
|
end
|
|
end
|
|
end
|
|
|
|
if mode == 1 then
|
|
return
|
|
end
|
|
|
|
::update::
|
|
|
|
this.inf_gui[player.name].updated = false
|
|
end
|
|
|
|
local function on_gui_elem_changed(event)
|
|
local element = event.element
|
|
local player = game.get_player(event.player_index)
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
if not element.valid then
|
|
return
|
|
end
|
|
local parent = element.parent
|
|
if not parent then
|
|
return
|
|
end
|
|
if parent.name ~= 'infinity_storage_inventory' then
|
|
return
|
|
end
|
|
local unit_number = tonumber(parent.parent.parent.name)
|
|
if tonumber(element.name) == unit_number then
|
|
return
|
|
end
|
|
|
|
local container = fetch_container(unit_number)
|
|
|
|
local button = event.button
|
|
local name = element.elem_value
|
|
|
|
if button == defines.mouse_button_type.right then
|
|
container.item = nil
|
|
container.count = 0
|
|
container.entity.clear_fluid_inside()
|
|
if this.inf_gui[player.name] then
|
|
this.inf_gui[player.name].updated = false
|
|
end
|
|
return
|
|
end
|
|
|
|
if not name then
|
|
return
|
|
end
|
|
container.item = name
|
|
container.count = 500000
|
|
|
|
if this.inf_gui[player.name] then
|
|
this.inf_gui[player.name].updated = false
|
|
end
|
|
end
|
|
|
|
local function on_gui_checked_state_changed(event)
|
|
local element = event.element
|
|
local player = game.get_player(event.player_index)
|
|
if not validate_player(player) then
|
|
return
|
|
end
|
|
if not element.valid then
|
|
return
|
|
end
|
|
local state = element.state and true or false
|
|
|
|
local pGui = this.inf_gui[player.name]
|
|
if not pGui then
|
|
return
|
|
end
|
|
|
|
local entity = pGui.entity
|
|
if not (entity and entity.valid) then
|
|
return
|
|
end
|
|
|
|
local unit_number = entity.unit_number
|
|
local container = fetch_container(unit_number)
|
|
if not container then
|
|
return
|
|
end
|
|
|
|
if element.name == 'private_container' then
|
|
container.private.state = state
|
|
elseif element.name == 'limit_storage' then
|
|
container.limit.state = state
|
|
elseif element.name == 'clear_checkbox' then
|
|
if container.item then
|
|
if not pGui.validate then
|
|
player.print(module_name .. 'Are you sure you want to clear all fluids?', Color.warning)
|
|
pGui.validate = true
|
|
Task.set_timeout_in_ticks(30, delay_refresh_main_frame_task_token,
|
|
{ player_index = player.index, unit_number = container.unit_number })
|
|
return
|
|
end
|
|
|
|
pGui.validate = nil
|
|
|
|
player.print(module_name .. 'Cleared all fluids.')
|
|
container.clear_fluid.state = false
|
|
container.item = nil
|
|
container.count = 0
|
|
container.entity.clear_fluid_inside()
|
|
Task.set_timeout_in_ticks(30, delay_refresh_main_frame_task_token,
|
|
{ player_index = player.index, unit_number = container.unit_number })
|
|
else
|
|
Task.set_timeout_in_ticks(30, delay_refresh_main_frame_task_token,
|
|
{ player_index = player.index, unit_number = container.unit_number })
|
|
end
|
|
return
|
|
elseif element.name == 'share_container' then
|
|
if container.share.name ~= 'Share name' then
|
|
container.direction.state = 'import'
|
|
if container.share.state then
|
|
remove_link(unit_number)
|
|
container.direction.state = 'export'
|
|
end
|
|
container.share.state = state
|
|
toggle_render(container)
|
|
else
|
|
player.print(module_name .. 'Please provide a valid share name.', Color.warning)
|
|
element.state = false
|
|
end
|
|
end
|
|
|
|
pGui.updated = false
|
|
end
|
|
|
|
Event.on_nth_tick(
|
|
10,
|
|
function ()
|
|
if not this or not this.enabled then
|
|
validate()
|
|
return
|
|
end
|
|
local fluid_prototypes = prototypes.fluid
|
|
update_container(fluid_prototypes)
|
|
end
|
|
)
|
|
|
|
Event.on_nth_tick(
|
|
5,
|
|
function ()
|
|
if not this or not this.enabled then
|
|
validate()
|
|
return
|
|
end
|
|
update_gui()
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
convert_to_infinite_container,
|
|
function (event)
|
|
local player = event.player
|
|
local inventory = player.get_main_inventory()
|
|
local player_item_count = inventory.get_item_count('coin')
|
|
|
|
if player_item_count >= this.cost_to_convert then
|
|
local entity = Gui.get_data(event.element)
|
|
if entity and entity.valid then
|
|
player.remove_item({ name = 'coin', count = this.cost_to_convert })
|
|
player.opened = nil
|
|
event.entity = entity
|
|
event.entity = entity
|
|
|
|
on_built_entity(event, true)
|
|
end
|
|
else
|
|
player.print(module_name .. 'Not enough coins.', Color.warning)
|
|
end
|
|
end
|
|
)
|
|
|
|
Event.add(
|
|
defines.events.on_gui_opened,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
if not player or not player.valid then
|
|
return
|
|
end
|
|
|
|
local panel = player.gui.relative
|
|
local entity = event.entity
|
|
|
|
if entity and entity.valid and this.valid_storage[entity.type] then
|
|
draw_convert_button(panel, entity)
|
|
end
|
|
|
|
gui_opened(event)
|
|
end
|
|
)
|
|
|
|
Event.add(
|
|
defines.events.on_gui_closed,
|
|
function (event)
|
|
local player = game.get_player(event.player_index)
|
|
if not player or not player.valid then
|
|
return
|
|
end
|
|
|
|
gui_closed(event)
|
|
|
|
local relative = player.gui.relative
|
|
local panel = relative[converter_frame_for_player_name]
|
|
if panel and panel.valid then
|
|
Gui.destroy(panel)
|
|
end
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
master_storage_btn_name,
|
|
function (event)
|
|
local player = event.player
|
|
local chest_gui_data = this.inf_gui[player.name]
|
|
if not chest_gui_data then
|
|
return
|
|
end
|
|
|
|
if not chest_gui_data.validation then
|
|
player.print('Are you sure you want to make this storage a master storage?', Color.warning)
|
|
chest_gui_data.validation = true
|
|
return
|
|
end
|
|
|
|
local entity = chest_gui_data.entity
|
|
if not entity or not entity.valid then
|
|
return
|
|
end
|
|
|
|
local source_container = fetch_container(entity.unit_number)
|
|
if not source_container then
|
|
player.print('This storage is not a valid storage.', Color.warning)
|
|
return
|
|
end
|
|
|
|
if source_container.mode ~= 3 then
|
|
player.print('This storage is not a slave storage.', Color.warning)
|
|
return
|
|
end
|
|
|
|
local destination_container = fetch_container(source_container.linked_to)
|
|
if not destination_container then
|
|
player.print('This storage is not a valid storage.', Color.warning)
|
|
return
|
|
end
|
|
|
|
if destination_container.mode ~= 1 then
|
|
player.print('This storage is not a master storage.', Color.warning)
|
|
return
|
|
end
|
|
|
|
make_master_storage(player, source_container, destination_container)
|
|
player.print('Successfully made this storage a master storage.', Color.success)
|
|
chest_gui_data.validation = nil
|
|
if chest_gui_data.frame and chest_gui_data.frame.valid then
|
|
chest_gui_data.frame.destroy()
|
|
end
|
|
end
|
|
)
|
|
|
|
Gui.on_click(
|
|
item_name_frame_name,
|
|
function (event)
|
|
local data = Gui.get_data(event.element)
|
|
if not data then
|
|
return
|
|
end
|
|
|
|
local _, _unit_number = fetch_share(event.player, data.share)
|
|
if _unit_number then
|
|
local container = fetch_container(data.unit_number)
|
|
container.linked_to = _unit_number
|
|
container.requested_fluid = data.name
|
|
|
|
local linked_container = fetch_container(_unit_number)
|
|
if linked_container then
|
|
if not linked_container.links then
|
|
linked_container.links = {}
|
|
end
|
|
if not linked_container.links[container.unit_number] then
|
|
linked_container.links[container.unit_number] = true
|
|
end
|
|
end
|
|
this.inf_gui[event.player.name].updated = false
|
|
toggle_render(container)
|
|
refresh_main_frame({ unit_number = container.unit_number, player = event.player })
|
|
end
|
|
end
|
|
)
|
|
|
|
Event.add(defines.events.on_gui_click, gui_click)
|
|
Event.add(defines.events.on_built_entity, on_built_entity)
|
|
Event.add(defines.events.on_pre_player_mined_item, on_pre_player_mined_item)
|
|
Event.add(defines.events.on_gui_selection_state_changed, state_changed)
|
|
Event.add(defines.events.on_entity_died, on_entity_died)
|
|
Event.add(defines.events.on_gui_elem_changed, on_gui_elem_changed)
|
|
Event.add(defines.events.on_gui_checked_state_changed, on_gui_checked_state_changed)
|
|
Event.add(defines.events.on_gui_text_changed, text_changed)
|
|
Event.add(
|
|
defines.events.on_player_removed,
|
|
function (event)
|
|
Public.remove_player(event.player_index)
|
|
end
|
|
)
|
|
|
|
Event.on_configuration_changed(
|
|
function ()
|
|
validate()
|
|
end
|
|
)
|
|
|
|
Commands.new('increase_fluid', 'Increases fluid capacity')
|
|
:require_role('infinity_storage')
|
|
:callback(function (player)
|
|
if player.selected and player.selected.unit_number then
|
|
local linked_container = fetch_container(player.selected.unit_number)
|
|
if linked_container and linked_container.count then
|
|
linked_container.count = linked_container.count + 5000000
|
|
player.print('Fluid capacity increased by 5000000.', Color.success)
|
|
else
|
|
player.print('Please select a container.', Color.warning)
|
|
end
|
|
else
|
|
player.print('Please select a container.', Color.warning)
|
|
end
|
|
end
|
|
)
|
|
|
|
|
|
Commands.new('toggle_storage_render', 'Changes the render state of the storage')
|
|
:require_role('infinity_storage')
|
|
:callback(function (player)
|
|
for _, container in pairs(this.main_containers) do
|
|
toggle_render(container)
|
|
end
|
|
player.print('[Infinity Storage] Render state changed.', Color.success)
|
|
end
|
|
)
|
|
|
|
return Public
|