196 lines
6.7 KiB
Lua
196 lines
6.7 KiB
Lua
local EXPORTER_NAME = "signal-exporter"
|
|
local EXPORT_INTERVAL = 1800 -- Ticks between file writes (1800 = 30s at 60 UPS)
|
|
|
|
local function init_global()
|
|
global.exporters = global.exporters or {}
|
|
global.open_guis = global.open_guis or {}
|
|
end
|
|
|
|
script.on_init(init_global)
|
|
script.on_configuration_changed(init_global)
|
|
|
|
local function export_combinator(unit_number, data)
|
|
local entity = data.entity
|
|
if not (entity and entity.valid) then
|
|
global.exporters[unit_number] = nil
|
|
return
|
|
end
|
|
|
|
local signals = {
|
|
game_tick = game.tick,
|
|
circuit_network = {
|
|
red = {},
|
|
green = {}
|
|
},
|
|
logistic_network = {}
|
|
}
|
|
|
|
local wires = {
|
|
[defines.wire_type.red] = "red",
|
|
[defines.wire_type.green] = "green"
|
|
}
|
|
|
|
for wire_type, color in pairs(wires) do
|
|
local network = entity.get_circuit_network(wire_type)
|
|
if network and network.signals then
|
|
for _, signal in ipairs(network.signals) do
|
|
local name = signal.signal.name
|
|
if name then
|
|
signals.circuit_network[color][name] = (signals.circuit_network[color][name] or 0) + signal.count
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local logistic_network = entity.surface.find_logistic_network_by_position(entity.position, entity.force)
|
|
if logistic_network then
|
|
local contents = logistic_network.get_contents()
|
|
for name, count in pairs(contents) do
|
|
signals.logistic_network[name] = count
|
|
end
|
|
end
|
|
|
|
local json_string = game.table_to_json(signals)
|
|
game.write_file("signal_export/" .. data.name .. ".json", json_string, false)
|
|
end
|
|
|
|
local function on_created(event)
|
|
local entity = event.created_entity or event.entity or event.destination
|
|
if not (entity and entity.valid) then return end
|
|
|
|
if entity.name == EXPORTER_NAME then
|
|
global.exporters[entity.unit_number] = {
|
|
entity = entity,
|
|
name = "combinator_" .. tostring(entity.unit_number)
|
|
}
|
|
end
|
|
end
|
|
|
|
local function on_destroyed(event)
|
|
local entity = event.entity
|
|
if not (entity and entity.valid) then return end
|
|
|
|
if entity.name == EXPORTER_NAME then
|
|
global.exporters[entity.unit_number] = nil
|
|
end
|
|
end
|
|
|
|
local build_events = {
|
|
defines.events.on_built_entity,
|
|
defines.events.on_robot_built_entity,
|
|
defines.events.script_raised_built,
|
|
defines.events.script_raised_revive
|
|
}
|
|
for _, e in ipairs(build_events) do
|
|
script.on_event(e, on_created)
|
|
end
|
|
|
|
local destroy_events = {
|
|
defines.events.on_player_mined_entity,
|
|
defines.events.on_robot_mined_entity,
|
|
defines.events.on_entity_died,
|
|
defines.events.script_raised_destroy
|
|
}
|
|
for _, e in ipairs(destroy_events) do
|
|
script.on_event(e, on_destroyed)
|
|
end
|
|
|
|
script.on_nth_tick(EXPORT_INTERVAL, function()
|
|
for unit_number, data in pairs(global.exporters) do
|
|
export_combinator(unit_number, data)
|
|
end
|
|
end)
|
|
|
|
script.on_event(defines.events.on_gui_opened, function(event)
|
|
local entity = event.entity
|
|
if entity and entity.valid and entity.name == EXPORTER_NAME then
|
|
local player = game.players[event.player_index]
|
|
local data = global.exporters[entity.unit_number]
|
|
if not data then return end
|
|
|
|
local screen = player.gui.screen
|
|
if screen["signal_exporter_gui"] then
|
|
screen["signal_exporter_gui"].destroy()
|
|
end
|
|
|
|
local frame = screen.add{type = "frame", name = "signal_exporter_gui", caption = "Configure Signal Exporter", direction = "vertical"}
|
|
frame.force_auto_center()
|
|
|
|
local name_flow = frame.add{type = "flow", name = "name_flow", direction = "horizontal"}
|
|
name_flow.style.vertical_align = "center"
|
|
name_flow.style.bottom_margin = 8
|
|
name_flow.add{type = "label", caption = "Combinator Name: "}
|
|
name_flow.add{type = "textfield", name = "exporter_name_input", text = data.name}
|
|
|
|
local button_flow = frame.add{type = "flow", name = "button_flow", direction = "horizontal"}
|
|
button_flow.add{type = "button", name = "exporter_save_button", caption = "Save & Close"}
|
|
button_flow.add{type = "button", name = "exporter_refresh_button", caption = "Export Now"}
|
|
|
|
player.opened = frame
|
|
global.open_guis[player.index] = entity.unit_number
|
|
end
|
|
end)
|
|
|
|
script.on_event(defines.events.on_gui_click, function(event)
|
|
local element = event.element
|
|
if element.name == "exporter_save_button" or element.name == "exporter_refresh_button" then
|
|
local player = game.players[event.player_index]
|
|
local unit_number = global.open_guis[player.index]
|
|
|
|
if unit_number and global.exporters[unit_number] then
|
|
local frame = player.gui.screen["signal_exporter_gui"]
|
|
if frame then
|
|
local new_name = frame.name_flow.exporter_name_input.text
|
|
global.exporters[unit_number].name = new_name
|
|
end
|
|
|
|
if element.name == "exporter_refresh_button" then
|
|
export_combinator(unit_number, global.exporters[unit_number])
|
|
player.print("Data manually exported to signals_" .. global.exporters[unit_number].name .. ".json")
|
|
end
|
|
end
|
|
|
|
if element.name == "exporter_save_button" then
|
|
if player.gui.screen["signal_exporter_gui"] then
|
|
player.gui.screen["signal_exporter_gui"].destroy()
|
|
end
|
|
global.open_guis[player.index] = nil
|
|
end
|
|
end
|
|
end)
|
|
|
|
script.on_event(defines.events.on_gui_closed, function(event)
|
|
if event.element and event.element.name == "signal_exporter_gui" then
|
|
event.element.destroy()
|
|
global.open_guis[event.player_index] = nil
|
|
end
|
|
end)
|
|
|
|
local function export_item_names_csv(event)
|
|
local player = game.players[event.player_index]
|
|
local csv_lines = { '"item_key","localised_name"' }
|
|
|
|
local function escape_csv_field(value)
|
|
if value == nil then return "" end
|
|
return string.gsub(tostring(value), '"', '""')
|
|
end
|
|
|
|
for _, item_prototype in pairs(game.item_prototypes) do
|
|
local key = item_prototype.name
|
|
local resolved_name = player.localise(item_prototype.localised_name)
|
|
local escaped_key = escape_csv_field(key)
|
|
local escaped_name = escape_csv_field(resolved_name)
|
|
table.insert(csv_lines, '"' .. escaped_key .. '","' .. escaped_name .. '"')
|
|
end
|
|
|
|
local csv_content = table.concat(csv_lines, "\n")
|
|
game.write_file("item_names.csv", csv_content, false, player.index)
|
|
player.print("Export complete. File saved to 'script-output/item_names.csv'.")
|
|
end
|
|
|
|
commands.add_command(
|
|
"export-item-names",
|
|
"Exports the internal name (key) and localised name for all game items to a CSV file.",
|
|
export_item_names_csv
|
|
)
|