182 lines
7.2 KiB
Lua

--[[
"name":"Foreman",
"title":"Foreman",
"author":"Choumiko (originally: JamesOFarrell)",
"homepage": "https://forums.factorio.com/viewtopic.php?f=92&t=14243",
"description":"A tool for manipulating blueprints"
--]]
local Event = require('__stdlib__/stdlib/event/event')
local Gui = require('__stdlib__/stdlib/event/gui')
local Position = require('__stdlib__/stdlib/area/position')
local Inventory = require('__stdlib__/stdlib/entity/inventory')
local table = require('__stdlib__/stdlib/utils/table')
local interface = require('__stdlib__/stdlib/scripts/interface')
local mod_gui = require('mod-gui')
local function get_or_create_mirror_button(player)
local flow = mod_gui.get_button_flow(player)
local button = flow['picker_mirror_button']
if not button then
button =
flow.add {
type = 'sprite-button',
name = 'picker_mirror_button',
sprite = 'picker-mirror-sprite',
style = mod_gui.button_style,
tooltip = {'blueprinter.btn-mirror'}
}
end
return button
end
local function show_bp_tools(event)
local player = game.get_player(event.player_index)
local bp = Inventory.get_blueprint(player.cursor_stack, true)
local button = get_or_create_mirror_button(player)
if bp and not Inventory.is_named_bp(bp, 'Belt brush') then
button.visible = true
else
button.visible = false
end
end
Event.register(defines.events.on_player_cursor_stack_changed, show_bp_tools)
local swap_sides = {
['left'] = 'right',
['right'] = 'left',
['in'] = 'out',
['out'] = 'in',
['input'] = 'output',
['output'] = 'input'
}
local rolling_stock = {
['locomotive'] = true,
['cargo-wagon'] = true,
['fluid-wagon'] = true,
['artillery-wagon'] = true
}
Event.generate_event_name('on_blueprint_mirrored')
function interface.on_blueprint_mirrored()
return Event.get_event_name('on_blueprint_mirrored')
end
local function get_mirrored_blueprint(blueprint)
local curves, others, stops, signals, tanks = 9, 0, 4, 4, 2
local smartTrains = remote.interfaces.st and remote.interfaces.st.getProxyPositions
local smartStops = {['smart-train-stop-proxy'] = {}, ['smart-train-stop-proxy-cargo'] = {}}
local smartSignal, smartCargo = {}, {}
local proxyKeys = function(trainStop)
local proxies = remote.call('st', 'getProxyPositions', trainStop)
local signal = proxies.signalProxy.x .. ':' .. proxies.signalProxy.y
local cargo = proxies.cargo.x .. ':' .. proxies.cargo.y
return {signal = signal, cargo = cargo}
end
local entities = blueprint.get_blueprint_entities()
local tiles = blueprint.get_blueprint_tiles()
if entities then
for i, ent in pairs(entities) do
local entType = game.entity_prototypes[ent.name] and game.entity_prototypes[ent.name].type
ent.direction = ent.direction or 0
if entType == 'curved-rail' then
ent.direction = (curves - ent.direction) % 8
elseif entType == 'rail-signal' or entType == 'rail-chain-signal' then
ent.direction = (signals - ent.direction) % 8
elseif entType == 'train-stop' then
if ent.name == 'smart-train-stop' and smartTrains then
local proxies = proxyKeys(ent)
smartStops['smart-train-stop-proxy'][proxies.signal] = {old = {direction = ent.direction, position = Position.copy(ent.position)}}
smartStops['smart-train-stop-proxy-cargo'][proxies.cargo] = {old = {direction = ent.direction, position = Position.copy(ent.position)}}
ent.direction = (stops - ent.direction) % 8
smartStops['smart-train-stop-proxy'][proxies.signal].new = ent
smartStops['smart-train-stop-proxy-cargo'][proxies.cargo].new = ent
else
ent.direction = (stops - ent.direction) % 8
end
elseif entType == 'lamp' then
if ent.name == 'smart-train-stop-proxy' then
ent.direction = 0
table.insert(smartSignal, {entity = {name = ent.name, position = Position.copy(ent.position)}, i = i})
end
elseif entType == 'constant-combinator' then
if ent.name == 'smart-train-stop-proxy-cargo' then
ent.direction = 0
table.insert(smartCargo, {entity = {name = ent.name, position = Position.copy(ent.position)}, i = i})
end
elseif entType == 'storage-tank' then
ent.direction = (tanks + ent.direction) % 8
elseif entType == 'splitter' then
ent.direction = (others - ent.direction) % 8
ent.input_priority = ent.input_priority and swap_sides[ent.input_priority]
ent.output_priority = ent.output_priority and swap_sides[ent.output_priority]
elseif entType == 'pipe-to-ground' then
if ent.name:find('%-clamped%-l$') then
ent.direction = (others - ent.direction + 2) % 8
else
ent.direction = (others - ent.direction) % 8
end
elseif rolling_stock[entType] then
ent.orientation = (ent.orientation + 0.5) % 1
else
ent.direction = (others - ent.direction) % 8
end
ent.position.x = -1 * ent.position.x
if ent.drop_position then
ent.drop_position.x = -1 * ent.drop_position.x
end
if ent.pickup_position then
ent.pickup_position.x = -1 * ent.pickup_position.x
end
end
end
for _, data in pairs(smartSignal) do
local proxy = data.entity
local stop = smartStops[proxy.name][proxy.position.x .. ':' .. proxy.position.y]
if stop then
local newPositions = remote.call('st', 'getProxyPositions', stop.new)
entities[data.i].position = newPositions.signalProxy
end
end
for _, data in pairs(smartCargo) do
local proxy = data.entity
local stop = smartStops[proxy.name][proxy.position.x .. ':' .. proxy.position.y]
if stop then
local newPositions = remote.call('st', 'getProxyPositions', stop.new)
entities[data.i].position = newPositions.cargo
end
end
if tiles then
for _, tile in pairs(tiles) do
tile.position.x = -1 * tile.position.x
end
end
return {entities = entities, tiles = tiles}
end
local function mirror_blueprint(event)
local player = game.players[event.player_index]
local blueprint = Inventory.get_blueprint(player.cursor_stack, true)
if blueprint then
local mirrored = get_mirrored_blueprint(blueprint)
blueprint.set_blueprint_entities(mirrored.entities)
blueprint.set_blueprint_tiles(mirrored.tiles)
local new_event = {
player_index = player.index,
blueprint = blueprint
}
Event.raise_event(Event.generate_event_name('on_blueprint_mirrored'), new_event)
end
end
Gui.on_click('picker_mirror_button', mirror_blueprint)
Event.register('picker-mirror-blueprint', mirror_blueprint)