Factorio-Paranoidal_mod/Robot256Lib/script/blueprint_replacement.lua

129 lines
4.2 KiB
Lua

--[[ Copyright (c) 2019 robot256 (MIT License)
* Project: Robot256Library
* File: blueprint.lua
* Description: Handlers for on_player_pipette, on_player_setup_blueprint, on_player_configured_blueprint.
* When player creates or edits a blueprint containing, or uses pipette on a non-craftable entity,
* these functions will replace it with the craftable entity if possible.
* event: Event parameter object.
* map: Dictionary mapping non-craftable entity names to craftable entity names.
Examples:
--== ON_PLAYER_CONFIGURED_BLUEPRINT EVENT ==--
-- ID 70, fires when you select a blueprint to place
--== ON_PLAYER_SETUP_BLUEPRINT EVENT ==--
-- ID 68, fires when you select an area to make a blueprint or copy
local function OnPlayerSetupBlueprint(event)
mapBlueprint(event,map)
end
--== ON_PLAYER_PIPETTE ==--
-- Fires when player presses 'Q'. We need to sneakily grab the correct item from inventory if it exists,
-- sneakily give the correct item in cheat mode, and fix the cursor ghost if any.
local function OnPlayerPipette(event)
mapPipette(event,map)
end
--]]
local function purgeBlueprint(bp,map)
-- Get Entity table from blueprint
local entities = bp.get_blueprint_entities()
-- Find any downgradable items and downgrade them
if entities and next(entities) then
for _,e in pairs(entities) do
if map[e.name] then
e.name = map[e.name]
end
end
-- Write tables back to the blueprint
bp.set_blueprint_entities(entities)
end
-- Find icons too
local icons = bp.blueprint_icons
if icons and next(icons) then
for _,i in pairs(icons) do
if i.signal.type == "item" then
if map[i.signal.name] then
i.signal.name = map[i.signal.name]
end
end
end
-- Write tables back to the blueprint
bp.blueprint_icons = icons
end
end
local function mapBlueprint(event,map)
-- Get Blueprint from player (LuaItemStack object)
-- If this is a Copy operation, BP is in cursor_stack
-- If this is a Blueprint operation, BP is in blueprint_to_setup
-- Need to use "valid_for_read" because "valid" returns true for empty LuaItemStack in cursor
local item1 = game.get_player(event.player_index).blueprint_to_setup
local item2 = game.get_player(event.player_index).cursor_stack
if item1 and item1.valid_for_read==true then
purgeBlueprint(item1,map)
elseif item2 and item2.valid_for_read==true and item2.is_blueprint==true then
purgeBlueprint(item2,map)
end
end
local function mapPipette(event,map)
local item = event.item
if map[item.name] then
-- Originally pipetted on an item of interest
-- Check current contents of cursor
local player = game.players[event.player_index]
local cursor = player.cursor_stack
if cursor.valid_for_read then
if map[cursor.name] then
local inventory = player.get_main_inventory()
local newName = map[cursor.name]
if event.used_cheat_mode then
local newItemStack = inventory.find_item_stack(newName)
if newItemStack then
-- Delete cheat-gotten wrong items, load correct items from inventory
cursor.set_stack(newItemStack)
inventory.remove(newItemStack)
else
-- Delete cheat-gotten wrong items, cheat-give correct items
cursor.set_stack({name=newName, count=game.item_prototypes[newName].stack_size})
end
else
-- Transform fairly-gotten wrong items into correct items
cursor.set_stack({name=newName, count=cursor.count})
end
end
else
if not event.used_cheat_mode then
local inventory = player.get_main_inventory()
local newName = map[item.name]
local newItemStack = inventory.find_item_stack(newName)
if newItemStack then
-- Load empty cursor with correct items from inventory
cursor.set_stack(newItemStack)
inventory.remove(newItemStack)
end
end
end
-- Check contents of cursor_ghost as well (can coexist with cursor_stack)
if player.cursor_ghost and map[player.cursor_ghost.name] then
player.cursor_ghost = map[player.cursor_ghost.name]
end
end
end
return {
purgeBlueprint = purgeBlueprint,
mapBlueprint = mapBlueprint,
mapPipette = mapPipette
}