809 lines
36 KiB
Lua
809 lines
36 KiB
Lua
require('util')
|
|
|
|
local lib = require('lib')
|
|
local config = require('config')
|
|
local Smarts = {} ---@class Smarts
|
|
|
|
--------------------------------------------------------------------------------------------------------------
|
|
---------- Local Helper functions
|
|
|
|
--------------------------------------------------------------------------------------------------------------
|
|
-- Classes
|
|
|
|
---@class ItemCycle
|
|
---@field name string
|
|
---@field type string
|
|
|
|
---@class EntityData
|
|
---@field cycle ItemCycle[]
|
|
---@field cycle_index int
|
|
|
|
|
|
--------------------------------------------------------------------------------------------------------------
|
|
---------- Local cycle functions
|
|
|
|
----- Container cycle
|
|
---@param entity LuaEntity
|
|
---@return ItemCycle[]
|
|
local function container_cycle(entity)
|
|
local cycle = {}
|
|
if entity and entity.valid and entity.get_inventory(defines.inventory.chest) then
|
|
local inventory = lib.get_keys(entity.get_inventory(defines.inventory.chest).get_contents())
|
|
for _, v in pairs(inventory) do
|
|
table.insert(cycle, { name = v, type = "item" })
|
|
end
|
|
end
|
|
return cycle
|
|
end
|
|
|
|
----- Decider/Arithmetic combinator cycle
|
|
---@param entity LuaEntity
|
|
---@return ItemCycle[]
|
|
local function decider_arithmetic_combinator_cycle(entity)
|
|
local cycle = {}
|
|
if entity and entity.valid then
|
|
local cb = entity.get_control_behavior() ---@cast cb LuaCombinatorControlBehavior
|
|
if cb and cb.signals_last_tick then
|
|
local signals = cb.signals_last_tick
|
|
for _, v in pairs(signals) do
|
|
table.insert(cycle, v.signal)
|
|
end
|
|
end
|
|
end
|
|
return cycle
|
|
end
|
|
|
|
----- DisplayPlate current sprite
|
|
---@param entity LuaEntity
|
|
---@return ItemCycle[]
|
|
local function simple_entity_with_owner_cycle(entity)
|
|
local remote_interface
|
|
if game.active_mods["IndustrialDisplayPlates"] then remote_interface = "IndustrialDisplayPlates" end
|
|
if game.active_mods["DisplayPlates"] then remote_interface = "DisplayPlates" end
|
|
|
|
local interfaces = remote.interfaces[remote_interface]
|
|
if (not interfaces.get_sprite) and (not interfaces.set_sprite) then return {} end
|
|
|
|
local rv = remote.call(remote_interface, "get_sprite", { entity = entity })
|
|
if (not rv) then return {} end
|
|
|
|
local cycle = { { type = rv.spritetype, name = rv.spritename } }
|
|
return cycle
|
|
end
|
|
|
|
----- Assembly Machine cycle
|
|
---@param entity LuaEntity
|
|
---@return ItemCycle[]
|
|
local function assembly_cycle(entity)
|
|
local cycle = {}
|
|
|
|
if entity and entity.valid and entity.get_recipe() then
|
|
local recipe = entity.get_recipe()
|
|
for _, v in pairs(recipe.products) do
|
|
table.insert(cycle, v)
|
|
end
|
|
for _, v in pairs(recipe.ingredients) do
|
|
table.insert(cycle, v)
|
|
end
|
|
end
|
|
|
|
return cycle
|
|
end
|
|
|
|
----- Constant Combinator cycle
|
|
---@param entity LuaEntity
|
|
---@return ItemCycle[]
|
|
local function constant_combinator_cycle(entity)
|
|
local cycle = {}
|
|
|
|
if entity and entity.valid then
|
|
local cb = entity.get_control_behavior() ---@cast cb LuaConstantCombinatorControlBehavior
|
|
if cb and cb.enabled then
|
|
local signals = cb.parameters
|
|
for _, v in pairs(signals) do
|
|
if v.signal.name then
|
|
table.insert(cycle, v.signal)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return cycle
|
|
end
|
|
|
|
--------------------------------------------------------------------------------------------------------------
|
|
---------- Local rename functions
|
|
|
|
---@param landing_pad_entity LuaEntity
|
|
---@param cycle ItemCycle[]
|
|
local function update_se_landing_pad_name(landing_pad_entity, cycle)
|
|
if landing_pad_entity.name ~= "se-rocket-landing-pad" then return end
|
|
|
|
-- If the destination is a SE landing pad use remote interface to rename the pad and show a flying text
|
|
global.entity_data[landing_pad_entity.unit_number] = global.entity_data[landing_pad_entity.unit_number] or {}
|
|
|
|
-- Check if the global dict tracking the entities being changed needs to be reset due to a new inventory
|
|
local entity = global.entity_data[landing_pad_entity.unit_number]
|
|
if entity == nil or entity.cycle == nil or (not table.compare(cycle, entity.cycle)) then
|
|
entity = entity or {}
|
|
entity.cycle = cycle
|
|
entity.cycle_index = 1
|
|
end
|
|
|
|
local item = entity.cycle[entity.cycle_index]
|
|
if (not item) then return end
|
|
|
|
local item_name
|
|
if config['use_Babelfish'] then
|
|
item_name = lib.find_name_in_babelfish_dictonary(item.name, item.type)
|
|
else
|
|
item_name = item.name
|
|
end
|
|
|
|
-- Get the name of the cargo rocket pad following the naming standard in the "MAP SETTINGS"
|
|
local name = lib.parse_string(config['se-rocket-landing-pad-name'], { lib.parse_signal_to_rich_text(item), item_name })
|
|
entity.cycle_index = entity.cycle_index + 1
|
|
if entity.cycle_index > #entity.cycle then entity.cycle_index = 1 end
|
|
|
|
-- Grab the current name and if the new name is different use the remote interface to change the name of the landing pad
|
|
local current_name = remote.call("space-exploration", "get_landing_pad_name",
|
|
{ unit_number = landing_pad_entity.unit_number })
|
|
if current_name ~= name then
|
|
landing_pad_entity.surface.create_entity { name = "flying-text", position = landing_pad_entity.position, text = name, color = lib.colors.white }
|
|
remote.call("space-exploration", "set_landing_pad_name", { unit_number = landing_pad_entity.unit_number, name = name })
|
|
end
|
|
|
|
end
|
|
|
|
---@param display_plate LuaEntity
|
|
---@param cycle ItemCycle[]
|
|
local function update_simple_entity_with_owner(display_plate, cycle)
|
|
|
|
local remote_interface
|
|
if game.active_mods["IndustrialDisplayPlates"] then remote_interface = "IndustrialDisplayPlates" end
|
|
if game.active_mods["DisplayPlates"] then remote_interface = "DisplayPlates" end
|
|
|
|
local interfaces = remote.interfaces[remote_interface]
|
|
if (not interfaces.get_sprite) and (not interfaces.set_sprite) then return end
|
|
|
|
local rv = remote.call(remote_interface, "get_sprite", { entity = display_plate })
|
|
if (not rv) then return end
|
|
|
|
global.entity_data[display_plate.unit_number] = global.entity_data[display_plate.unit_number] or {}
|
|
local entity = global.entity_data[display_plate.unit_number]
|
|
|
|
if entity == nil or entity.cycle == nil or not table.compare(cycle, entity.cycle) then
|
|
entity = entity or {}
|
|
entity.cycle = cycle
|
|
entity.cycle_index = 1
|
|
end
|
|
|
|
if entity.cycle[entity.cycle_index].type == "virtual" then
|
|
entity.cycle[entity.cycle_index].type = "virtual-signal"
|
|
end
|
|
local new_sprite = entity.cycle[entity.cycle_index].type .. "/" .. entity.cycle[entity.cycle_index].name
|
|
|
|
local msg = lib.parse_signal_to_rich_text(entity.cycle[entity.cycle_index]) .. " " .. entity.cycle[entity.cycle_index].name
|
|
display_plate.surface.create_entity { name = "flying-text", position = display_plate.position, text = msg, color = lib.colors.white }
|
|
remote.call(remote_interface, "set_sprite", { entity = display_plate, sprite = new_sprite })
|
|
|
|
entity.cycle_index = entity.cycle_index + 1
|
|
if entity.cycle_index > #entity.cycle then entity.cycle_index = 1 end
|
|
end
|
|
|
|
----------
|
|
|
|
---comment
|
|
---@param mtype any
|
|
---@param multiplier double
|
|
---@param stack any
|
|
---@param previous_value int
|
|
---@param recipe LuaRecipe
|
|
---@param speed any
|
|
---@param additive any
|
|
---@param special? float
|
|
---@return int
|
|
local function update_stack(mtype, multiplier, stack, previous_value, recipe, speed, additive, special)
|
|
if mtype == "additional-paste-settings-per-stack-size" then
|
|
if additive and previous_value ~= nil then
|
|
if special then
|
|
return previous_value * special
|
|
else
|
|
if game.item_prototypes[stack.name] and game.item_prototypes[stack.name].stack_size then
|
|
return math.floor(previous_value + (game.item_prototypes[stack.name].stack_size * multiplier))
|
|
else
|
|
return 0
|
|
end
|
|
end
|
|
else
|
|
if special then
|
|
if game.item_prototypes[stack.name] and game.item_prototypes[stack.name].stack_size then
|
|
return math.floor(game.item_prototypes[stack.name].stack_size * special)
|
|
else
|
|
return 0
|
|
end
|
|
else
|
|
if game.item_prototypes[stack.name] and game.item_prototypes[stack.name].stack_size then
|
|
return math.floor(game.item_prototypes[stack.name].stack_size * multiplier)
|
|
else
|
|
return 0
|
|
end
|
|
end
|
|
end
|
|
elseif mtype == "additional-paste-settings-per-recipe-size" then
|
|
local amount = 0
|
|
if recipe then
|
|
for i = 1, #recipe.ingredients do
|
|
if recipe.ingredients[i].name == stack.name then
|
|
amount = recipe.ingredients[i].amount
|
|
break
|
|
end
|
|
end
|
|
for i = 1, #recipe.products do
|
|
if recipe.products[i].name == stack.name then
|
|
if recipe.products[i].amount then
|
|
amount = recipe.products[i].amount
|
|
else
|
|
amount = recipe.products[i].amount_max
|
|
end
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if additive and previous_value ~= nil then
|
|
return math.floor(previous_value + amount * multiplier)
|
|
else
|
|
return math.floor(amount * multiplier)
|
|
end
|
|
elseif mtype == "additional-paste-settings-per-time-size" then
|
|
local amount = 0
|
|
if recipe then
|
|
for i = 1, #recipe.ingredients do
|
|
if recipe.ingredients[i].name == stack.name then
|
|
amount = recipe.ingredients[i].amount
|
|
break
|
|
end
|
|
end
|
|
for i = 1, #recipe.products do
|
|
if recipe.products[i].name == stack.name then
|
|
if recipe.products[i].amount then
|
|
amount = recipe.products[i].amount
|
|
else
|
|
amount = recipe.products[i].amount_max
|
|
end
|
|
break
|
|
end
|
|
end
|
|
if additive and previous_value ~= nil then
|
|
return math.ceil(previous_value + amount * multiplier * speed / recipe.energy)
|
|
else
|
|
return math.ceil(amount * multiplier * speed / recipe.energy)
|
|
end
|
|
end
|
|
else
|
|
error "error"
|
|
end
|
|
return 0
|
|
end
|
|
|
|
function Smarts.clear_requester_chest(from, to)
|
|
if from == to then
|
|
if to.prototype.logistic_mode == "requester" or to.prototype.logistic_mode == "buffer" then
|
|
for i = 1, to.request_slot_count do
|
|
to.clear_request_slot(i)
|
|
end
|
|
elseif to.prototype.logistic_mode == "storage" then
|
|
to.storage_filter = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
function Smarts.clear_inserter_settings(from, to, player, special)
|
|
if from == to and
|
|
settings.get_player_settings(player)["additional-paste-settings-paste-clear-inserter-filter-on-paste-over"].value then
|
|
local ctrl = to.get_or_create_control_behavior()
|
|
ctrl.logistic_condition = nil
|
|
ctrl.circuit_condition = nil
|
|
ctrl.connect_to_logistic_network = false
|
|
ctrl.circuit_mode_of_operation = defines.control_behavior.inserter.circuit_mode_of_operation.none
|
|
end
|
|
end
|
|
|
|
---Copy machine to constant combinator
|
|
---@param from LuaEntity
|
|
---@param to LuaEntity
|
|
---@param player LuaPlayer
|
|
function Smarts.assembly_to_constant_combinator(from, to, player)
|
|
local multiplier = settings.get_player_settings(player)["additional-paste-settings-options-combinator-multiplier-value"].value ---@cast multiplier double
|
|
local mtype = settings.get_player_settings(player)["additional-paste-settings-options-combinator-multiplier-type"].value
|
|
local additive = settings.get_player_settings(player)["additional-paste-settings-options-sumup"].value
|
|
local recipe = from.get_recipe()
|
|
local amount = 0 ---@type int
|
|
local per_recipe_size = ("additional-paste-settings-per-recipe-size" == settings.get_player_settings(player)["additional-paste-settings-options-requester-multiplier-type"].value)
|
|
|
|
local current = nil
|
|
local found = false
|
|
local msg = ""
|
|
local ctrl = to.get_or_create_control_behavior() ---@cast ctrl LuaConstantCombinatorControlBehavior
|
|
if recipe then
|
|
for k = 1, #recipe.ingredients do
|
|
current = recipe.ingredients[k]
|
|
found = false
|
|
---@type uint
|
|
for i = 1, ctrl.signals_count do
|
|
local s = ctrl.get_signal(i)
|
|
if s.signal ~= nil and s.signal.name == current.name then
|
|
amount = update_stack(mtype, multiplier, { name = current.name }, s.count, recipe, from.crafting_speed, additive)
|
|
ctrl.set_signal(i, { signal = { type = current.type, name = current.name }, count = amount })
|
|
msg = msg .. "[img=" .. current.type .. "." .. current.name .. "] = " .. amount .. " "
|
|
found = true
|
|
end
|
|
end
|
|
|
|
if (not found) then
|
|
---@type uint
|
|
for i = 1, ctrl.signals_count do
|
|
local s = ctrl.get_signal(i)
|
|
if s.signal == nil then
|
|
amount = update_stack(mtype, multiplier, { name = current.name }, nil, recipe, from.crafting_speed, additive)
|
|
ctrl.set_signal(i, { signal = { type = current.type, name = current.name }, count = amount })
|
|
msg = msg .. "[img=" .. current.type .. "." .. current.name .. "] = " .. amount .. " "
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
to.surface.create_entity { name = "flying-text", position = to.position, text = msg, color = lib.colors.white }
|
|
end
|
|
end
|
|
|
|
function Smarts.assembly_to_logistic_chest(from, to, player, special)
|
|
-- this needs additional logic from events on_vanilla_pre_paste and on_vanilla_paste to correctly set the filter
|
|
if to.prototype.logistic_mode == "requester" or to.prototype.logistic_mode == "buffer" then
|
|
global.event_backup[from.position.x .. "-" .. from.position.y .. "-" .. to.position.x .. "-" .. to.position.y] = { gamer = player.index, stacks = {} }
|
|
elseif to.prototype.logistic_mode == "storage" then
|
|
if from.get_recipe() ~= nil then
|
|
local msg
|
|
local proto = game.item_prototypes[from.get_recipe().name]
|
|
if proto then
|
|
to.storage_filter = proto
|
|
msg = "Filter applied [img=item." .. from.get_recipe().name .. "]"
|
|
to.surface.create_entity { name = "flying-text", position = to.position, text = msg, color = lib.colors.white }
|
|
else
|
|
local products = from.get_recipe().products
|
|
for _, product in pairs(products) do
|
|
if product.type and product.type == "item" then
|
|
proto = game.item_prototypes[product.name]
|
|
break
|
|
end
|
|
end
|
|
if proto then
|
|
to.storage_filter = proto
|
|
msg = "Filter applied [img=item." .. proto.name .. "]"
|
|
to.surface.create_entity { name = "flying-text", position = to.position, text = msg, color = lib.colors.white }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function rename_train_stop(station)
|
|
local station_name
|
|
local entity = global.entity_data[station.unit_number]
|
|
local item = entity.cycle[entity.cycle_index]
|
|
|
|
if (not item) then return end
|
|
|
|
local item_name
|
|
if config['use_Babelfish'] then
|
|
item_name = lib.find_name_in_babelfish_dictonary(item.name, item.type)
|
|
else
|
|
item_name = item.name
|
|
end
|
|
|
|
if entity.mode == "Load" then station_name = lib.parse_string(config['station_name_load'], { lib.parse_signal_to_rich_text(item), item_name }) end
|
|
if entity.mode == "Unload" then station_name = lib.parse_string(config['station_name_unload'], { lib.parse_signal_to_rich_text(item), item_name }) end
|
|
if entity.mode == "Unload" then entity.cycle_index = entity.cycle_index + 1 end
|
|
if entity.mode == "Load" then entity.mode = "Unload" else entity.mode = "Load" end
|
|
if entity.cycle_index > #entity.cycle then entity.cycle_index = 1 end
|
|
|
|
if station.backer_name ~= station_name then
|
|
station.backer_name = station_name
|
|
station.surface.create_entity { name = "flying-text", position = station.position, text = station.backer_name, color = lib.colors.white }
|
|
end
|
|
end
|
|
|
|
local function update_station(to, cycle)
|
|
global.entity_data[to.unit_number] = global.entity_data[to.unit_number] or {}
|
|
local entity = global.entity_data[to.unit_number]
|
|
|
|
if entity == nil or entity.cycle == nil or (not table.compare(cycle, entity.cycle)) then
|
|
entity.mode = "Load"
|
|
entity.cycle = cycle
|
|
entity.cycle_index = 1
|
|
end
|
|
|
|
rename_train_stop(to)
|
|
end
|
|
|
|
function Smarts.constant_combinator_to_train_stop(from, to, player, special)
|
|
local cycle = constant_combinator_cycle(from)
|
|
if #cycle > 0 then update_station(to, cycle) end
|
|
end
|
|
|
|
function Smarts.decider_arithmetic_combinator_to_train_stop(from, to, player, special)
|
|
local cycle = decider_arithmetic_combinator_cycle(from)
|
|
if #cycle > 0 then update_station(to, cycle) end
|
|
end
|
|
|
|
function Smarts.decider_arithmetic_combinator_to_container(from, to, player, special)
|
|
local cycle = decider_arithmetic_combinator_cycle(from)
|
|
if #cycle == 0 then return end
|
|
update_se_landing_pad_name(to, cycle)
|
|
end
|
|
|
|
function Smarts.simple_entity_with_owner_to_container(from, to, player, special)
|
|
if to.name == "se-rocket-landing-pad" then
|
|
local cycle = simple_entity_with_owner_cycle(from)
|
|
if #cycle == 0 then return end
|
|
update_se_landing_pad_name(to, cycle)
|
|
end
|
|
end
|
|
|
|
function Smarts.constant_combinator_to_container(from, to, player, special)
|
|
if to.name == "se-rocket-landing-pad" then
|
|
local cycle = constant_combinator_cycle(from)
|
|
if #cycle > 0 then update_se_landing_pad_name(to, cycle) end
|
|
end
|
|
end
|
|
|
|
function Smarts.assembly_to_container(from, to, player, special)
|
|
if to.name == "se-rocket-landing-pad" then
|
|
local cycle = assembly_cycle(from)
|
|
if #cycle > 0 then update_se_landing_pad_name(to, cycle) end
|
|
end
|
|
end
|
|
|
|
function Smarts.container_to_container(from, to, player, special)
|
|
if to.name == "se-rocket-landing-pad" then
|
|
local cycle = container_cycle(from)
|
|
update_se_landing_pad_name(to, cycle)
|
|
end
|
|
end
|
|
|
|
function Smarts.decider_arithmetic_combinator_to_simple_entity_with_owner(from, to, player, special)
|
|
local cycle = decider_arithmetic_combinator_cycle(from)
|
|
if #cycle > 0 then update_simple_entity_with_owner(to, cycle) end
|
|
end
|
|
|
|
function Smarts.constant_combinator_to_simple_entity_with_owner(from, to, player, special)
|
|
local cycle = constant_combinator_cycle(from)
|
|
if #cycle > 0 then update_simple_entity_with_owner(to, cycle) end
|
|
end
|
|
|
|
function Smarts.assembly_to_simple_entity_with_owner(from, to, player, special)
|
|
local cycle = assembly_cycle(from)
|
|
if #cycle > 0 then update_simple_entity_with_owner(to, cycle) end
|
|
end
|
|
|
|
function Smarts.container_to_simple_entity_with_owner(from, to, player, special)
|
|
local cycle = container_cycle(from)
|
|
if #cycle > 0 then update_simple_entity_with_owner(to, cycle) end
|
|
end
|
|
|
|
function Smarts.container_to_train_stop(from, to, player, special)
|
|
local cycle = container_cycle(from)
|
|
if #cycle > 0 then update_station(to, cycle) end
|
|
end
|
|
|
|
function Smarts.assembly_to_train_stop(from, to, player, special)
|
|
local cycle = assembly_cycle(from)
|
|
if #cycle > 0 then update_station(to, cycle) end
|
|
end
|
|
|
|
function Smarts.assembly_to_transport_belt(from, to, player, special)
|
|
if (not settings.get_player_settings(player)["additional-paste-settings-paste-to-belt-enabled"].value) then
|
|
return
|
|
end
|
|
|
|
local ctrl = to.get_or_create_control_behavior()
|
|
local c1 = ctrl.get_circuit_network(defines.wire_type.red)
|
|
local c2 = ctrl.get_circuit_network(defines.wire_type.green)
|
|
|
|
local fromRecipe = from.get_recipe()
|
|
|
|
if fromRecipe == nil then
|
|
if c1 == nil and c2 == nil then
|
|
ctrl.logistic_condition = nil
|
|
ctrl.connect_to_logistic_network = false
|
|
else
|
|
ctrl.circuit_condition = nil
|
|
ctrl.enable_disable = false
|
|
end
|
|
else
|
|
local product = fromRecipe.products[1].name
|
|
local item = game.item_prototypes[product]
|
|
|
|
if item ~= nil then
|
|
local comparator = settings.get_player_settings(player)["additional-paste-settings-options-comparator-value"].value
|
|
local multiplier = settings.get_player_settings(player)["additional-paste-settings-options-transport_belt-multiplier-value"].value ---@cast multiplier double
|
|
local mtype = settings.get_player_settings(player)["additional-paste-settings-options-transport_belt-multiplier-type"].value
|
|
local additive = settings.get_player_settings(player)["additional-paste-settings-options-sumup"].value
|
|
local amount = update_stack(mtype, multiplier, item, nil, fromRecipe, from.crafting_speed, additive, special)
|
|
if c1 == nil and c2 == nil then
|
|
if ctrl.connect_to_logistic_network and
|
|
ctrl.logistic_condition["condition"]["first_signal"]["name"] == product then
|
|
if ctrl.logistic_condition["condition"]["constant"] ~= nil then
|
|
amount = update_stack(mtype, multiplier, item, ctrl.logistic_condition["condition"]["constant"],
|
|
fromRecipe, from.crafting_speed, additive, special)
|
|
end
|
|
else
|
|
ctrl.connect_to_logistic_network = true
|
|
end
|
|
ctrl.logistic_condition = { condition = { comparator = comparator, first_signal = { type = "item", name = product }, constant = amount } }
|
|
to.surface.create_entity { name = "flying-text", position = to.position, text = "[img=item." .. product .. "] " .. comparator .. " " .. math.floor(amount), color = lib.colors.white }
|
|
else
|
|
if ctrl.enable_disable and ctrl.circuit_condition["condition"]["first_signal"]["name"] == product then
|
|
if ctrl.logistic_condition["condition"]["constant"] ~= nil then
|
|
amount = update_stack(mtype, multiplier, item, ctrl.circuit_condition["condition"]["constant"], fromRecipe, from.crafting_speed, additive, special)
|
|
end
|
|
else
|
|
ctrl.enable_disable = true
|
|
end
|
|
ctrl.circuit_condition = { condition = { comparator = comparator, first_signal = { type = "item", name = product }, constant = amount } }
|
|
to.surface.create_entity { name = "flying-text", position = to.position, text = "[img=item." .. product .. "] " .. comparator .. " " .. math.floor(amount), color = lib.colors.white }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Smarts.assembly_to_inserter(from, to, player, special)
|
|
local ctrl = to.get_or_create_control_behavior()
|
|
local c1 = ctrl.get_circuit_network(defines.wire_type.red)
|
|
local c2 = ctrl.get_circuit_network(defines.wire_type.green)
|
|
|
|
local fromRecipe = from.get_recipe()
|
|
|
|
if fromRecipe == nil then
|
|
if c1 == nil and c2 == nil then
|
|
ctrl.logistic_condition = nil
|
|
ctrl.connect_to_logistic_network = false
|
|
else
|
|
ctrl.circuit_condition = nil
|
|
ctrl.circuit_mode_of_operation = defines.control_behavior.inserter.circuit_mode_of_operation.none
|
|
end
|
|
else
|
|
local product = fromRecipe.products[1].name
|
|
local item = game.item_prototypes[product]
|
|
|
|
if item ~= nil then
|
|
local comparator = settings.get_player_settings(player)["additional-paste-settings-options-comparator-value"].value
|
|
local multiplier = settings.get_player_settings(player)["additional-paste-settings-options-inserter-multiplier-value"].value ---@cast multiplier double
|
|
local mtype = settings.get_player_settings(player)["additional-paste-settings-options-inserter-multiplier-type"].value
|
|
local additive = settings.get_player_settings(player)["additional-paste-settings-options-sumup"].value
|
|
local amount = update_stack(mtype, multiplier, item, nil, fromRecipe, from.crafting_speed, additive, special)
|
|
if c1 == nil and c2 == nil then
|
|
if ctrl.connect_to_logistic_network and
|
|
ctrl.logistic_condition["condition"]["first_signal"]["name"] == product then
|
|
if ctrl.logistic_condition["condition"]["constant"] ~= nil then
|
|
amount = update_stack(mtype, multiplier, item, ctrl.logistic_condition["condition"]["constant"],
|
|
fromRecipe, from.crafting_speed, additive, special)
|
|
end
|
|
else
|
|
ctrl.connect_to_logistic_network = true
|
|
end
|
|
ctrl.logistic_condition = { condition = { comparator = comparator, first_signal = { type = "item", name = product }, constant = amount } }
|
|
to.surface.create_entity { name = "flying-text", position = to.position, text = "[img=item." .. product .. "] " .. comparator .. " " .. math.floor(amount), color = lib.colors.white }
|
|
else
|
|
if ctrl.circuit_mode_of_operation ==
|
|
defines.control_behavior.inserter.circuit_mode_of_operation.enable_disable and
|
|
ctrl.circuit_condition["condition"]["first_signal"]["name"] == product then
|
|
if ctrl.logistic_condition["condition"]["constant"] ~= nil then
|
|
amount = update_stack(mtype, multiplier, item, ctrl.circuit_condition["condition"]["constant"],
|
|
fromRecipe, from.crafting_speed, additive, special)
|
|
end
|
|
else
|
|
ctrl.circuit_mode_of_operation = defines.control_behavior.inserter.circuit_mode_of_operation.enable_disable
|
|
end
|
|
ctrl.circuit_condition = { condition = { comparator = comparator, first_signal = { type = "item", name = product }, constant = amount } }
|
|
to.surface.create_entity { name = "flying-text", position = to.position, text = "[img=item." .. product .. "] " .. comparator .. " " .. math.floor(amount), color = lib.colors.white }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Smarts.on_hotkey_pressed(event)
|
|
local player = game.players[event.player_index]
|
|
local special = nil
|
|
|
|
if event.input_name and event.input_name == "additional-paste-settings-hotkey-alt" then
|
|
special = 0.5
|
|
end
|
|
|
|
if player ~= nil and player.connected then
|
|
local from = player.entity_copy_source
|
|
local to = player.selected
|
|
|
|
if from ~= nil and to ~= nil then
|
|
local key = from.type .. "|" .. to.type
|
|
local act = Smarts.actions[key]
|
|
|
|
if act ~= nil then
|
|
act(from, to, player, special)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---@param event EventData.on_pre_entity_settings_pasted
|
|
function Smarts.on_vanilla_pre_paste(event)
|
|
if event.source.type == "assembling-machine" and event.destination.type == "logistic-container" and (event.destination.prototype.logistic_mode == "requester" or event.destination.prototype.logistic_mode == "buffer") then
|
|
local evt = global.event_backup[event.source.position.x .. "-" .. event.source.position.y .. "-" .. event.destination.position.x .. "-" .. event.destination.position.y]
|
|
local range = event.destination.request_slot_count
|
|
|
|
if evt ~= nil then
|
|
---@type uint
|
|
for i = 1, range do
|
|
local j = event.destination.get_request_slot(i)
|
|
if j == nil then
|
|
-- evt.stacks[i] = {}
|
|
else
|
|
evt.stacks[j.name] = j.count
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---@param event EventData.on_entity_settings_pasted
|
|
function Smarts.on_vanilla_paste(event)
|
|
local evt = global.event_backup[event.source.position.x .. "-" .. event.source.position.y .. "-" .. event.destination.position.x .. "-" .. event.destination.position.y]
|
|
|
|
if evt ~= nil and event.source.type == "assembling-machine" and event.destination.type == "logistic-container" and (event.destination.prototype.logistic_mode == "requester" or event.destination.prototype.logistic_mode == "buffer") then
|
|
local result = {}
|
|
local multiplier = settings.get_player_settings(event.player_index)["additional-paste-settings-options-requester-multiplier-value"].value ---@cast multiplier double
|
|
local mtype = settings.get_player_settings(event.player_index)["additional-paste-settings-options-requester-multiplier-type"].value
|
|
local recipe = event.source.get_recipe() ---@cast recipe LuaRecipe
|
|
local speed = event.source.crafting_speed
|
|
local additive = settings.get_player_settings(event.player_index)["additional-paste-settings-options-sumup"].value
|
|
local invertPaste = settings.get_player_settings(event.player_index)["additional-paste-settings-options-invert-buffer"].value and event.destination.prototype.logistic_mode == "buffer"
|
|
if invertPaste and event.destination.prototype.logistic_mode == "buffer" then
|
|
mtype = "additional-paste-settings-per-stack-size"
|
|
multiplier = settings.get_player_settings(event.player_index)["additional-paste-settings-options-invert-buffer-multiplier-value"].value ---@cast multiplier double
|
|
end
|
|
|
|
local post_stacks = {}
|
|
---@type uint
|
|
for i = 1, event.destination.request_slot_count do
|
|
local stack = event.destination.get_request_slot(i)
|
|
if stack then
|
|
post_stacks[stack.name] = stack.count
|
|
if (not evt.stacks[stack.name]) then
|
|
evt.stacks[stack.name] = 0
|
|
end
|
|
end
|
|
end
|
|
|
|
for k, v in pairs(evt.stacks) do
|
|
local prior = { name = k, count = v }
|
|
local post = { name = k, count = post_stacks[k] }
|
|
|
|
if prior ~= {} then
|
|
if result[prior.name] ~= nil then
|
|
-- update_stack(mtype, multiplier, stack, previous_value, recipe, speed, additive, special)
|
|
result[prior.name].count = update_stack(mtype, multiplier, prior, result[prior.name].count, recipe, speed, additive)
|
|
else
|
|
result[prior.name] = { name = prior.name, count = prior.count }
|
|
end
|
|
end
|
|
|
|
if post ~= nil then
|
|
if invertPaste then
|
|
if result[post.name] ~= nil then
|
|
result[post.name].count = update_stack(mtype, -1 * multiplier, post, result[post.name].count, recipe, speed, additive)
|
|
else
|
|
result[post.name] = { name = post.name, count = 0 }
|
|
end
|
|
else
|
|
if result[post.name] ~= nil then
|
|
result[post.name].count = update_stack(mtype, multiplier, post, result[post.name].count, recipe, speed, additive)
|
|
else
|
|
result[post.name] = { name = post.name,
|
|
count = update_stack(mtype, multiplier, post, nil, recipe, speed, additive) }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if invertPaste and recipe then
|
|
for k, product in pairs(recipe.products) do
|
|
if result[product.name] ~= nil then
|
|
result[product.name].count = update_stack(mtype, multiplier, result[product.name], result[product.name].count, recipe, speed, additive)
|
|
else
|
|
result[product.name] = {
|
|
name = product.name,
|
|
count = update_stack(mtype, multiplier, { name = product.name }, game.item_prototypes[product.name].stack_size, recipe, speed, additive)
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
---@type uint
|
|
for i = 1, event.destination.request_slot_count do
|
|
event.destination.clear_request_slot(i)
|
|
end
|
|
|
|
local i = 1
|
|
local msg = ""
|
|
for k, v in pairs(result) do
|
|
if v and v.count and v.count > 0 then
|
|
event.destination.set_request_slot(v, i)
|
|
msg = msg .. "[img=item." .. v.name .. "] = " .. v.count .. " "
|
|
i = i + 1
|
|
end
|
|
end
|
|
|
|
event.destination.surface.create_entity { name = "flying-text", position = event.destination.position, text = msg, color = lib.colors.white }
|
|
global.event_backup[event.source.position.x .. "-" .. event.source.position.y .. "-" .. event.destination.position.x .. "-" .. event.destination.position.y] = nil
|
|
end
|
|
end
|
|
|
|
function Smarts.get_translations()
|
|
global.locale_dictionaries = remote.call("Babelfish", "get_translations")
|
|
end
|
|
|
|
-- ---@type table<string, fun(name:string, value: number)>
|
|
-- TeamMember.actions = {
|
|
-- ["bob"] = TeamMember.GuiRecreateForPlayer
|
|
-- }
|
|
|
|
-- local x = TeamMember.actions["dave"]
|
|
|
|
-- ---------------------------------------------------------------
|
|
|
|
-- ---@alias test table<string, function>
|
|
|
|
-- ---@type test
|
|
-- TeamMember.actions1 = {
|
|
-- ["bob"] = TeamMember.GuiRecreateForPlayer
|
|
-- }
|
|
|
|
---@type table<string, fun(from: LuaEntity, to: LuaEntity, player?: LuaPlayer|nil, special?: number|nil)>
|
|
Smarts.actions = {
|
|
-- SE cargo landing pad actions
|
|
["container|container"] = Smarts.container_to_container,
|
|
["logistic-container|container"] = Smarts.container_to_container,
|
|
["arithmetic-combinator|container"] = Smarts.decider_arithmetic_combinator_to_container,
|
|
["decider-combinator|container"] = Smarts.decider_arithmetic_combinator_to_container,
|
|
["constant-combinator|container"] = Smarts.constant_combinator_to_container,
|
|
["assembling-machine|container"] = Smarts.assembly_to_container,
|
|
|
|
-- SE + DisplayPlate actions
|
|
["simple-entity-with-owner|container"] = Smarts.simple_entity_with_owner_to_container,
|
|
|
|
-- DisplayPlate actions
|
|
["container|simple-entity-with-owner"] = Smarts.container_to_simple_entity_with_owner,
|
|
["logistic-container|simple-entity-with-owner"] = Smarts.container_to_simple_entity_with_owner,
|
|
["arithmetic-combinator|simple-entity-with-owner"] = Smarts.decider_arithmetic_combinator_to_simple_entity_with_owner,
|
|
["decider-combinator|simple-entity-with-owner"] = Smarts.decider_arithmetic_combinator_to_simple_entity_with_owner,
|
|
["constant-combinator|simple-entity-with-owner"] = Smarts.constant_combinator_to_simple_entity_with_owner,
|
|
["assembling-machine|simple-entity-with-owner"] = Smarts.assembly_to_simple_entity_with_owner,
|
|
|
|
-- Train station actions
|
|
["constant-combinator|train-stop"] = Smarts.constant_combinator_to_train_stop,
|
|
["decider-combinator|train-stop"] = Smarts.decider_arithmetic_combinator_to_train_stop,
|
|
["arithmetic-combinator|train-stop"] = Smarts.decider_arithmetic_combinator_to_train_stop,
|
|
["container|train-stop"] = Smarts.container_to_train_stop,
|
|
["assembling-machine|train-stop"] = Smarts.assembly_to_train_stop,
|
|
|
|
-- Old actions
|
|
["assembling-machine|transport-belt"] = Smarts.assembly_to_transport_belt,
|
|
["assembling-machine|inserter"] = Smarts.assembly_to_inserter,
|
|
["assembling-machine|logistic-container"] = Smarts.assembly_to_logistic_chest,
|
|
["assembling-machine|constant-combinator"] = Smarts.assembly_to_constant_combinator,
|
|
["logistic-container|logistic-container"] = Smarts.clear_requester_chest,
|
|
["inserter|inserter"] = Smarts.clear_inserter_settings
|
|
}
|
|
|
|
return Smarts
|