139 lines
4.9 KiB
Lua
139 lines
4.9 KiB
Lua
local _cursor = {}
|
|
|
|
---@param player LuaPlayer
|
|
---@param blueprint_entities BlueprintEntity[]
|
|
local function set_cursor_blueprint(player, blueprint_entities)
|
|
local script_inventory = game.create_inventory(1)
|
|
local blank_slot = script_inventory[1]
|
|
|
|
blank_slot.set_stack{name="fp_cursor_blueprint"}
|
|
blank_slot.set_blueprint_entities(blueprint_entities)
|
|
player.add_to_clipboard(blank_slot)
|
|
player.activate_paste()
|
|
script_inventory.destroy()
|
|
end
|
|
|
|
|
|
---@param player LuaPlayer
|
|
---@param text LocalisedString
|
|
function _cursor.create_flying_text(player, text)
|
|
player.create_local_flying_text{text=text, create_at_cursor=true}
|
|
end
|
|
|
|
---@param player LuaPlayer
|
|
---@param line FPLine
|
|
---@param object FPMachine | FPBeacon
|
|
---@return boolean success
|
|
function _cursor.set_entity(player, line, object)
|
|
local entity_prototype = game.entity_prototypes[object.proto.name]
|
|
if entity_prototype.has_flag("not-blueprintable") or not entity_prototype.has_flag("player-creation")
|
|
or entity_prototype.items_to_place_this == nil then
|
|
util.cursor.create_flying_text(player, {"fp.put_into_cursor_failed", entity_prototype.localised_name})
|
|
return false
|
|
end
|
|
|
|
local module_list = {}
|
|
for _, module in pairs(ModuleSet.get_in_order(object.module_set)) do
|
|
module_list[module.proto.name] = module.amount
|
|
end
|
|
|
|
local blueprint_entity = {
|
|
entity_number = 1,
|
|
name = object.proto.name,
|
|
position = {0, 0},
|
|
items = module_list,
|
|
recipe = (object.class == "Machine") and line.recipe.proto.name or nil
|
|
}
|
|
|
|
set_cursor_blueprint(player, {blueprint_entity})
|
|
return true
|
|
end
|
|
|
|
---@param player LuaPlayer
|
|
---@param items { [string]: number }
|
|
---@return boolean success
|
|
function _cursor.set_item_combinator(player, items)
|
|
local combinator_proto = game.entity_prototypes["constant-combinator"]
|
|
if combinator_proto == nil then
|
|
util.cursor.create_flying_text(player, {"fp.blueprint_no_combinator_prototype"})
|
|
return false
|
|
elseif not next(items) then
|
|
util.cursor.create_flying_text(player, {"fp.impossible_to_blueprint_fluid"})
|
|
return false
|
|
end
|
|
local filter_limit = combinator_proto.item_slot_count
|
|
|
|
local blueprint_entities = {} ---@type BlueprintEntity[]
|
|
local current_combinator, current_filter_count = nil, 0
|
|
local next_entity_number, next_position = 1, {0, 0}
|
|
|
|
for proto_name, item_amount in pairs(items) do
|
|
if not current_combinator or current_filter_count == filter_limit then
|
|
current_combinator = {
|
|
entity_number = next_entity_number,
|
|
name = "constant-combinator",
|
|
tags = {fp_item_combinator = true},
|
|
position = next_position,
|
|
control_behavior = {filters = {}},
|
|
connections = {{green = {}}} -- filled in below
|
|
}
|
|
table.insert(blueprint_entities, current_combinator)
|
|
|
|
next_entity_number = next_entity_number + 1
|
|
next_position = {next_position[1] + 1, 0}
|
|
current_filter_count = 0
|
|
end
|
|
|
|
current_filter_count = current_filter_count + 1
|
|
table.insert(current_combinator.control_behavior.filters, {
|
|
signal = {type = 'item', name = proto_name},
|
|
count = math.max(item_amount, 1), -- make sure amounts < 1 are not excluded
|
|
index = current_filter_count
|
|
})
|
|
end
|
|
|
|
---@param main_entity BlueprintEntity
|
|
---@param other_entity BlueprintEntity
|
|
local function connect_if_entity_exists(main_entity, other_entity)
|
|
if other_entity ~= nil then
|
|
local entry = {entity_id = other_entity.entity_number}
|
|
table.insert(main_entity.connections[1].green, entry)
|
|
end
|
|
end
|
|
|
|
for index, entity in ipairs(blueprint_entities) do
|
|
connect_if_entity_exists(entity, blueprint_entities[index-1])
|
|
if not next(entity.connections[1].green) then entity.connections = nil end
|
|
end
|
|
|
|
set_cursor_blueprint(player, blueprint_entities)
|
|
return true
|
|
end
|
|
|
|
---@param player LuaPlayer
|
|
---@param proto FPItemPrototype | FPFuelPrototype
|
|
---@param amount number
|
|
function _cursor.add_to_item_combinator(player, proto, amount)
|
|
if proto.type ~= "item" then
|
|
util.cursor.create_flying_text(player, {"fp.impossible_to_blueprint_fluid"})
|
|
return
|
|
end
|
|
|
|
local items = {}
|
|
local blueprint_entities = player.get_blueprint_entities()
|
|
if blueprint_entities ~= nil then
|
|
for _, entity in pairs(blueprint_entities) do
|
|
if entity.tags ~= nil and entity.tags["fp_item_combinator"] then
|
|
for _, filter in pairs(entity.control_behavior.filters) do
|
|
items[filter.signal.name] = filter.count
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
items[proto.name] = (items[proto.name] or 0) + amount
|
|
util.cursor.set_item_combinator(player, items) -- don't care about success here
|
|
end
|
|
|
|
return _cursor
|