1. What did you do?
I am working to update a mod for 2.0 that intercepts blueprint construction requests in the on_pre_build() event. It searches the get_blueprint_entities() list for instances the modded entities to do some additional setup.
Specifically, it adds a hook to on_pre_build() that executes the following code snippet:
if player.is_cursor_blueprint() then
local entities = nil
if player.cursor_stack and player.cursor_stack.is_blueprint_book then
local bp = player.cursor_stack.get_inventory(defines.inventory.item_main)[player.cursor_stack.active_index]
entities = bp.get_blueprint_entities()
elseif player.cursor_stack and player.cursor_stack.is_blueprint then
local bp = player.cursor_stack.item
entities = bp.get_blueprint_entities()
elseif player.cursor_record and (player.cursor_record.type == "blueprint-book" or player.cursor_record.type == "blueprint") then
entities = player.cursor_record.get_blueprint_entities()
end
... continues
2. What happens?
In the examples below blueprints of a single entity are sufficient (no modded content required). Starting a new freeplay game and placing the stone furnace is enough as long as you have preexisting blueprints and blueprint books in your blueprint library.
[works] Copy/paste (ctrl-c, ctrl-v) works via player.cursor_stack.is_blueprint
[works] Copying, placing the result into the inventory (or directly on the quickbar), then selecting and placing the blueprint via player.cursor_stack.is_blueprint
[works] Selecting a blueprint book from inventory, scroll-selecting a blueprint, and placing it via player.cursor_stack.is_blueprint_book
[works] Opening the blueprint library, selecting a blueprint, and placing it via blueprint.cursor_record
[crash] Opening the blueprint library, selecting a blueprint book, scroll-selecting a blueprint, and placing it
The failure when sourcing from the library occurs as the player.cursor_stack == nil. Then, although player.cursor_record is a LuaRecord and player.cursor_record.type == "blueprint-book", the call to player.cursor_record.get_blueprint_entities() crashes with "Record is not a BlueprintRecord."
When player.cursor_record.type == "blueprint" (i.e., the fourth scenario) the call to player.cursor_record.get_blueprint_entities() works as expected.
3. What did you expect to happen?
From the LuaRecord API page, I expected player.cursor_record to properly be a BlueprintBookRecord when it's type was "blueprint-book."
Access to the currently-selected blueprint in the cursor should behave correctly regardless of the source of a blueprint (and blueprint-book). At minimum, I would expect read-only access to the selected blueprint through the player.cursor_stack (as an item) or player.cursor_record (as a library entry).
Tangentially: When selecting a blueprint directly from the Blueprint Library, player.cursor_record does populate with data but there is nothing like an active_index into player.cursor_record.contents[???] or player.cursor_record.get_active_blueprint(). Perhaps there is some complication with nested blueprints.
References: viewtopic.php?p=597386
4. Does it happen always, once, or sometimes?
Consistently replicated from a new game.
[2.0.19] Mod using get_blueprint_entities fails when building directly from blueprint library
-
- Manual Inserter
- Posts: 1
- Joined: Sun Nov 17, 2024 11:27 pm
- Contact:
[2.0.19] Mod using get_blueprint_entities fails when building directly from blueprint library
- Attachments
-
- factorio-current.log
- (8.29 KiB) Downloaded 4 times
-
- BlueprintCrash_0.0.1.zip
- (16.91 KiB) Downloaded 4 times
Re: [2.0.19] Mod using get_blueprint_entities fails when building directly from blueprint library
Probably not a bug, but definitely a missing API feature to read the active_index of a Blueprint Book Records (like you already can on Blueprint Book items). See modding interface requests 120533 and 117993.
When player selects a blueprint-book, you have to write code to find which blueprint in the book is actually selected by the player and then ask that blueprint for its entities. The book item doesn't know what it's placing, and the active item might be an upgrade or deconstruction planner for all it knows. Your example does this for the cursor_stack handler. Not sure why you expected cursor_record to behave differently. It's definitely a missing API feature.
When player selects a blueprint-book, you have to write code to find which blueprint in the book is actually selected by the player and then ask that blueprint for its entities. The book item doesn't know what it's placing, and the active item might be an upgrade or deconstruction planner for all it knows. Your example does this for the cursor_stack handler. Not sure why you expected cursor_record to behave differently. It's definitely a missing API feature.
My mods: Multiple Unit Train Control, Smart Artillery Wagons
Maintainer of Vehicle Wagon 2, Cargo Ships, Honk
Maintainer of Vehicle Wagon 2, Cargo Ships, Honk