153 lines
4.8 KiB
Lua

--(( Copy Chest ))--
local Event = require('__stdlib__/stdlib/event/event')
local Player = require('__stdlib__/stdlib/event/player')
local interface = require('__stdlib__/stdlib/scripts/interface')
local chest_types = {
['container'] = true,
['logistic-container'] = true,
['cargo-wagon'] = true
}
local api_check = 'picker_chest_contents_mover_check'
local function flying_text(player, text, position)
return player.create_local_flying_text{text = text, position = position}
end
-- Copy on empty spot, nil copy_src
-- on paste, check for copy_src
-- Should allow stacking keybinds
local function copy_chest(event)
local player, pdata = Player.get(event.player_index)
local chest = player.selected
if not chest then
pdata.copy_src = nil
return
end
if pdata.copy_src then
-- Used for same keybind
return
end
if not chest_types[chest.type] then
return flying_text(player, {'chest.containers'}, chest.position)
end
if global.blacklisted_chests[chest.name] then
return flying_text(player, {'chest.blacklisted', chest.localised_name}, chest.position)
end
local p_force, c_force = player.force, chest.force
if not (p_force == c_force or c_force.name == 'neutral' or c_force.get_friend(p_force)) then
return flying_text(player, {'cant-transfer-from-enemy-structures'}, chest.position)
end
local inventory = chest.get_inventory(defines.inventory.chest)
if not inventory.is_empty() then
pdata.copy_src = {
inv = inventory,
surface = chest.surface,
ent = chest,
tick = event.tick
}
return flying_text(player, {'chest.copy-src'}, chest.position)
else
return flying_text(player, {'chest.empty-src'}, chest.position)
end
end
Event.register('picker-copy-chest', copy_chest)
local function paste_chest(event)
local player, pdata = Player.get(event.player_index)
local chest = player.selected
if not chest then
return
end
if not (pdata.copy_src and pdata.copy_src.tick ~= event.tick) then
return
end
if not chest_types[chest.type] then
return flying_text(player, {'chest.containers'}, chest.position)
end
local p_force, c_force = player.force, chest.force
if not (p_force == c_force or c_force.name == 'neutral' or c_force.get_friend(p_force)) then
return flying_text(player, {'cant-transfer-to-enemy-structures'}, chest.position)
end
if global.blacklisted_chests[chest.name] then
return flying_text(player, {'chest.blacklisted', chest.localised_name}, chest.position)
end
if not (pdata.copy_src.inv and pdata.copy_src.inv.valid and not pdata.copy_src.inv.is_empty()) then
pdata.copy_src = nil
return flying_text(player, {'chest.no-copy-from'}, chest.position)
end
if chest == pdata.copy_src.ent then
return flying_text(player, {'chest.same-inventory'}, chest.position)
end
if pdata.copy_src.surface ~= chest.surface and not settings.global['picker-copy-between-surfaces'].value then
return flying_text(player, {'chest.not-same-surface'}, chest.position)
end
local interfaces = remote.interfaces
for name in pairs(interfaces) do
if interfaces[name][api_check] then
if not remote.call(name, api_check, pdata.copy_src.ent, chest) then
return
end
end
end
local count = chest.get_item_count()
local src = pdata.copy_src.inv
for i = 1, #src do
local stack = src[i]
if stack.valid_for_read then
stack.count = stack.count - chest.insert(stack)
end
end
if src.is_empty() then
pdata.copy_src = nil
return flying_text(player, {'chest.all-moved'}, chest.position)
elseif count == chest.get_item_count() then
return flying_text(player, {'chest.none-moved'}, chest.position)
else
return flying_text(player, {'chest.some-moved'}, chest.position)
end
end
Event.register('picker-paste-chest', paste_chest)
local function update_global()
global.blacklisted_chests = global.blacklisted_chests or {}
end
Event.register(Event.core_events.init_and_config, update_global)
function interface.set_blacklisted_chests(names, remove)
global.blacklisted_chests = global.blacklisted_chests or {}
if type(names) == 'string' then
global.blacklisted_chests[names] = (not remove and true) or nil
return true
elseif type(names) == 'table' then
for _, name in pairs(names) do
global.blacklisted_chests[name] = (not remove and true) or nil
end
return true
end
end
function interface.get_blacklisted_chests()
global.blacklisted_chests = global.blacklisted_chests or {}
return global.blacklisted_chests
end