172 lines
6.1 KiB
Lua
172 lines
6.1 KiB
Lua
--[[
|
|
"name": "BlueprintExtensions",
|
|
"title": "Blueprint Extensions",
|
|
"author": "Dewin",
|
|
"contact": "https://github.com/dewiniaid/BlueprintExtensions",
|
|
"homepage": "https://github.com/dewiniaid/BlueprintExensions",
|
|
"description": "Adds tools for updating and placing blueprints."
|
|
--]]
|
|
local Event = require('__stdlib__/stdlib/event/event')
|
|
local Player = require('__stdlib__/stdlib/event/player')
|
|
local Inventory = require('__stdlib__/stdlib/entity/inventory')
|
|
local lib = require('__PickerAtheneum__/utils/lib')
|
|
|
|
local evt = defines.events
|
|
|
|
local CLONED_BLUEPRINT = 'picker-bp-updater'
|
|
local VERSION_PATTERN = '(v[.]?)(%d)$' -- Matches version number at end of blueprints.
|
|
local DEFAULT_VERSION = ' v.2'
|
|
|
|
local AWAITING_GUI = 1
|
|
local AWAITING_BP = 2
|
|
|
|
local Updater = {}
|
|
|
|
local function increment_version(v, n)
|
|
return v .. (n + 1)
|
|
end
|
|
|
|
local function get_or_create_buffer(player, pdata)
|
|
if not (pdata.buffer_inventory and pdata.buffer_inventory.valid) then
|
|
pdata.buffer_inventory = lib.create_buffer_corpse(player, true).get_inventory(defines.inventory.character_corpse)
|
|
end
|
|
return pdata.buffer_inventory
|
|
end
|
|
|
|
local function load_stack(pdata)
|
|
if pdata.stored_bp and pdata.stored_bp.valid_for_read then
|
|
return pdata.stored_bp
|
|
end
|
|
end
|
|
|
|
local function save_stack(player, pdata, stack)
|
|
local inv = get_or_create_buffer(player, pdata)
|
|
pdata.stored_bp = inv[1]
|
|
pdata.stored_bp.set_stack(stack)
|
|
end
|
|
|
|
local rolling_stock = {
|
|
['locomotive'] = true,
|
|
['cargo-wagon'] = true,
|
|
['fluid-wagon'] = true,
|
|
['artillery-wagon'] = true
|
|
}
|
|
|
|
-- Capabilities related to updating blueprints.
|
|
function Updater.clone(event)
|
|
local player, pdata = Player.get(event.player_index)
|
|
local bp = Inventory.get_blueprint(player.cursor_stack, true)
|
|
if bp then
|
|
local updater = {
|
|
name = bp.name,
|
|
label = bp.label,
|
|
icons = bp.blueprint_icons,
|
|
status = nil
|
|
}
|
|
|
|
for _, ent in pairs(bp.get_blueprint_entities()) do
|
|
if rolling_stock[game.entity_prototypes[ent.name].type] then
|
|
updater.trains = true
|
|
updater.fuel = ent.items and true or false
|
|
elseif ent.station and ent.station ~= "" then
|
|
updater.stations = true
|
|
end
|
|
end
|
|
|
|
-- Create replacer tool, drop orignal back into inventory
|
|
if player.clear_cursor() then
|
|
pdata.updater = updater
|
|
player.cursor_stack.set_stack(CLONED_BLUEPRINT)
|
|
if updater.label then
|
|
player.cursor_stack.label = updater.label
|
|
end
|
|
end -- Warning about not being able to clean?
|
|
end
|
|
end
|
|
|
|
function Updater.on_selected_area(event)
|
|
if event.item == CLONED_BLUEPRINT then
|
|
local alt = (event.name == defines.events.on_player_alt_selected_area)
|
|
|
|
local player, pdata = Player.get(event.player_index)
|
|
local cursor = player.cursor_stack
|
|
|
|
-- Handle blueprint replacer.
|
|
if pdata.updater then
|
|
local area = event.area
|
|
cursor.set_stack(pdata.updater.name)
|
|
cursor.create_blueprint {
|
|
surface = player.surface,
|
|
force = player.force,
|
|
always_include_tiles = true,
|
|
include_station_names=pdata.updater.stations,
|
|
include_trains=pdata.updater.trains,
|
|
area = area
|
|
}
|
|
|
|
if not cursor.is_blueprint_setup() then
|
|
-- Empty blueprint area?
|
|
return cursor.set_stack(CLONED_BLUEPRINT)
|
|
end
|
|
|
|
local label = pdata.updater.label or 'v.1'
|
|
if label then
|
|
cursor.blueprint_icons = pdata.updater.icons
|
|
|
|
local versioning = player.mod_settings[alt and 'picker-bp-updater-alt-version-increment' or 'picker-bp-updater-version-increment'].value
|
|
if versioning ~= 'off' then
|
|
local found
|
|
label, found = label:gsub(VERSION_PATTERN, increment_version)
|
|
if found == 0 and versioning == 'on' then
|
|
label = label .. DEFAULT_VERSION
|
|
end
|
|
end
|
|
cursor.label = label
|
|
end
|
|
|
|
-- Move this blueprint to a temporary item
|
|
local stack = player.cursor_stack
|
|
stack.set_stack(save_stack(player, pdata.updater, stack)) -- returns nil, effectivly calling clear()
|
|
pdata.updater.status = AWAITING_GUI
|
|
player.opened = load_stack(pdata.updater)
|
|
else
|
|
cursor.clear()
|
|
end
|
|
end
|
|
end
|
|
|
|
function Updater.on_gui_opened(event)
|
|
-- If opening an item, this means our target blueprint was closed at some point and that any
|
|
-- on_player_configured_blueprint events we see are nonsense.
|
|
if event.gui_type == defines.gui_type.item then
|
|
local _, pdata = Player.get(event.player_index)
|
|
if pdata.updater then
|
|
pdata.updater.status = pdata.updater.status == AWAITING_GUI and AWAITING_BP or nil
|
|
end
|
|
end
|
|
end
|
|
|
|
function Updater.on_player_configured_blueprint(event)
|
|
local player, pdata = Player.get(event.player_index)
|
|
if pdata.updater and pdata.updater.status == AWAITING_BP then
|
|
if not player.clear_cursor() then
|
|
-- rarest of rare edge cases
|
|
player.print({'blueprint-updater.error_cannot_set_stack', {'item-name.'..pdata.updater.name}})
|
|
local ground = player.surface.create_entity{name = 'item-on-ground', position = player.position, stack = {name = pdata.updater.name, amount = 1}}
|
|
ground.stack.set_stack(load_stack(pdata))
|
|
else
|
|
player.cursor_stack.set_stack(load_stack(pdata.updater))
|
|
end
|
|
end
|
|
pdata.updater = nil -- Nuke this.
|
|
end
|
|
|
|
if settings.startup['picker-tool-bp-updater'].value then
|
|
Event.register({evt.on_player_selected_area, evt.on_player_alt_selected_area}, Updater.on_selected_area)
|
|
Event.register('picker-bp-update', Updater.clone)
|
|
Event.register(evt.on_gui_opened, Updater.on_gui_opened)
|
|
Event.register(evt.on_player_configured_blueprint, Updater.on_player_configured_blueprint)
|
|
end
|
|
|
|
return Updater
|