1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2024-12-12 10:04:40 +02:00
RedMew/blueprint_helper.lua
2018-05-20 16:29:05 +01:00

313 lines
10 KiB
Lua

-- Soft mod version of Blueprint Flipper and Turner https://mods.factorio.com/mods/Marthen/Blueprint_Flip_Turn
local Event = require 'utils.event'
local Gui = require 'utils.gui'
local function getBlueprintCursorStack(player)
local cursor = player.cursor_stack
if
cursor.valid_for_read and (cursor.name == 'blueprint' or cursor.name == 'blueprint-book') and
cursor.is_blueprint_setup()
then --check if is a blueprint, work in book as well
return cursor
end
return nil
end
local function flip_v(player)
local cursor = getBlueprintCursorStack(player)
if cursor then
local ents = cursor.get_blueprint_entities()
if ents then
for i = 1, #ents do
local dir = ents[i].direction or 0
if ents[i].name == 'curved-rail' then
ents[i].direction = (13 - dir) % 8
elseif ents[i].name == 'storage-tank' then
if ents[i].direction == 2 or ents[i].direction == 6 then
ents[i].direction = 4
else
ents[i].direction = 2
end
elseif ents[i].name == 'rail-signal' or ents[i].name == 'rail-chain-signal' then
if dir == 1 then
ents[i].direction = 7
elseif dir == 2 then
ents[i].direction = 6
elseif dir == 3 then
ents[i].direction = 5
elseif dir == 5 then
ents[i].direction = 3
elseif dir == 6 then
ents[i].direction = 2
elseif dir == 7 then
ents[i].direction = 1
end
elseif ents[i].name == 'train-stop' then
if dir == 2 then
ents[i].direction = 6
elseif dir == 6 then
ents[i].direction = 2
end
else
ents[i].direction = (12 - dir) % 8
end
ents[i].position.y = -ents[i].position.y
if ents[i].drop_position then
ents[i].drop_position.y = -ents[i].drop_position.y
end
if ents[i].pickup_position then
ents[i].pickup_position.y = -ents[i].pickup_position.y
end
end
cursor.set_blueprint_entities(ents)
end
if cursor.get_blueprint_tiles() ~= nil then
local ents = cursor.get_blueprint_tiles()
for i = 1, #ents do
local dir = ents[i].direction or 0
ents[i].direction = (12 - dir) % 8
ents[i].position.y = -ents[i].position.y
end
cursor.set_blueprint_tiles(ents)
end
end
end
local function flip_h(player)
local cursor = getBlueprintCursorStack(player)
if cursor then
local ents = cursor.get_blueprint_entities()
if ents then
for i = 1, #ents do
local dir = ents[i].direction or 0
if ents[i].name == 'curved-rail' then
ents[i].direction = (9 - dir) % 8
elseif ents[i].name == 'storage-tank' then
if ents[i].direction == 2 or ents[i].direction == 6 then
ents[i].direction = 4
else
ents[i].direction = 2
end
elseif ents[i].name == 'rail-signal' or ents[i].name == 'rail-chain-signal' then
if dir == 0 then
ents[i].direction = 4
elseif dir == 1 then
ents[i].direction = 3
elseif dir == 3 then
ents[i].direction = 1
elseif dir == 4 then
ents[i].direction = 0
elseif dir == 5 then
ents[i].direction = 7
elseif dir == 7 then
ents[i].direction = 5
end
elseif ents[i].name == 'train-stop' then
if dir == 0 then
ents[i].direction = 4
elseif dir == 4 then
ents[i].direction = 0
end
else
ents[i].direction = (16 - dir) % 8
end
ents[i].position.x = -ents[i].position.x
if ents[i].drop_position then
ents[i].drop_position.x = -ents[i].drop_position.x
end
if ents[i].pickup_position then
ents[i].pickup_position.x = -ents[i].pickup_position.x
end
end
cursor.set_blueprint_entities(ents)
end
if cursor.get_blueprint_tiles() ~= nil then
local ents = cursor.get_blueprint_tiles()
for i = 1, #ents do
local dir = ents[i].direction or 0
ents[i].direction = (16 - dir) % 8
ents[i].position.x = -ents[i].position.x
end
cursor.set_blueprint_tiles(ents)
end
end
end
local function valid_filter(entity_name)
local prototype = game.entity_prototypes[entity_name]
if not prototype then
return false
end
-- 'not-blueprintable' doesn't seem to work - grilledham 2018.05.20
return prototype.has_flag('player-creation') and not prototype.has_flag('placeable-off-grid')
end
local function convert(player, data)
local cursor = getBlueprintCursorStack(player)
if not cursor then
return
end
local entities = cursor.get_blueprint_entities()
if not entities then
return
end
local filters = {}
for _, filter in pairs(data) do
local from = filter.from.elem_value
local to = filter.to.elem_value
if from and to then
if valid_filter(from) and valid_filter(to) then
filters[from] = to
else
player.print('invalid filter: ' .. from .. ' => ' .. to)
end
end
end
for _, e in ipairs(entities) do
local to_name = filters[e.name]
if to_name then
e.name = to_name
end
end
cursor.set_blueprint_entities(entities)
end
-- Gui implementation.
local main_button_name = Gui.uid_name()
local main_frame_name = Gui.uid_name()
local flip_h_button_name = Gui.uid_name()
local flip_v_button_name = Gui.uid_name()
local convert_button_name = Gui.uid_name()
local function player_joined(event)
local player = game.players[event.player_index]
if not player or not player.valid then
return
end
if player.gui.top[main_button_name] ~= nil then
return
end
player.gui.top.add {name = main_button_name, type = 'sprite-button', sprite = 'item/blueprint'}
end
local function toggle(event)
local left = event.player.gui.left
local main_frame = left[main_frame_name]
if main_frame and main_frame.valid then
Gui.remove_data_recursivly(main_frame)
main_frame.destroy()
else
main_frame =
left.add {
type = 'frame',
name = main_frame_name,
direction = 'vertical',
caption = 'Blueprint Helper'
}
local scroll_pane =
main_frame.add {type = 'scroll-pane', direction = 'vertical', vertical_scroll_policy = 'auto'}
scroll_pane.style.maximal_height = 500
-- Flipper.
local flipper_frame = scroll_pane.add {type = 'frame', caption = 'Flipper', direction = 'vertical'}
flipper_frame.add {
type = 'label',
caption = 'With blueprint in cursor click on button below to flip blueprint.'
}
flipper_frame.add {
type = 'label',
caption = 'Obviously this wont work correctly with refineries or chemical plants.'
}
flipper_frame.add {
type = 'button',
name = flip_h_button_name,
caption = 'Flip Horizontal'
}
flipper_frame.add {
type = 'button',
name = flip_v_button_name,
caption = 'Flip Vertical'
}
-- Converter.
local filter_frame = scroll_pane.add {type = 'frame', caption = 'Entity Converter', direction = 'vertical'}
filter_frame.add {type = 'label', caption = 'Set filters then with blueprint in cursor click convert'}
local filter_table = filter_frame.add {type = 'table', column_count = 13}
local filters = {}
for _ = 1, 3 do
for _ = 1, 3 do
local filler = filter_table.add {type = 'label'}
filler.style.minimal_width = 16
local from_filter =
filter_table.add {
type = 'choose-elem-button',
elem_type = 'entity'
}
filter_table.add {type = 'label', caption = '=>'}
local to_filter =
filter_table.add {
type = 'choose-elem-button',
elem_type = 'entity'
}
table.insert(filters, {from = from_filter, to = to_filter})
end
local filler = filter_table.add {type = 'label'}
filler.style.minimal_width = 16
end
local filter_button = filter_frame.add {type = 'button', name = convert_button_name, caption = 'convert'}
Gui.set_data(filter_button, filters)
main_frame.add {type = 'button', name = main_button_name, caption = 'close'}
end
end
Gui.on_click(main_button_name, toggle)
Gui.on_click(
flip_h_button_name,
function(event)
flip_h(event.player)
end
)
Gui.on_click(
flip_v_button_name,
function(event)
flip_v(event.player)
end
)
Gui.on_click(
convert_button_name,
function(event)
local data = Gui.get_data(event.element)
convert(event.player, data)
end
)
Event.add(defines.events.on_player_joined_game, player_joined)