Confusing behavior of LuaSurface can_place_entity

Place to get help with not working mods / modding interface.
robot256
Smart Inserter
Smart Inserter
Posts: 1327
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Confusing behavior of LuaSurface can_place_entity

Post by robot256 »

TL;DR I cannot figure out how to make the "forced" parameter of LuaSurface::can_place_entity() change the result of the function.

LuaSurface::can_place_entity() has a "forced" parameter with the following description: "If true, entities that can be marked for deconstruction are ignored. Only used if build_check_type is either manual_ghost, script_ghost or blueprint_ghost."

EDIT: It appears that the "forced" parameter DOES change the behavior when the blocking entity is already marked for deconstruction. Therefore, the documentation would appear to be accurate if it stated "If true, entities that are marked for deconstruction are ignored." Unfortunately this does not help my use case.

This would be great for me, because I am trying to update Auto Deconstruct with logic to identify which pipe prototypes can be built in a location after the mining drill is removed. I need a simple way to determine if the tiles under the drill will collide with a particular pipe prototype, while the drill is still in place. I thought that can_place_entity() would be usable for this task.

However, as you can see below, no combination of options will give "false" for building over water and "true" for building over a deconstructible entity. Am I mistaken how this API function is supposed to work? Are the docs incomplete? Should I revert to directly reading the tile collision masks?

All tests can be replicated in Vanilla 2.0.75 with the attached save file.

Simple building fails on water tiles, succeeds on empty concrete, and fails on a colliding entity (respectively), as expected:

Code: Select all

/c game.print(game.surfaces["nauvis"].can_place_entity{name="pipe", position={-21.5,-38.5}})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="pipe", position={-14.5,-38.5}})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="pipe", position={-7.5,-38.5}})
false
But when actually placing the ghosts, the colliding entity returns false regardless of the "forced" flag being set or not (specifying the player force also doesn't help):

Code: Select all

/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-21.5,-38.5}, forced=false, build_check_type=defines.build_check_type.blueprint_ghost})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-14.5,-38.5}, forced=false, build_check_type=defines.build_check_type.blueprint_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-7.5,-38.5}, forced=false, build_check_type=defines.build_check_type.blueprint_ghost})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-21.5,-38.5}, forced=true, build_check_type=defines.build_check_type.blueprint_ghost})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-14.5,-38.5}, forced=true, build_check_type=defines.build_check_type.blueprint_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-7.5,-38.5}, forced=true, build_check_type=defines.build_check_type.blueprint_ghost})
false
Using the "script-ghost" build check type does not seem to check collision masks at all, and always returns true even when not forced and over water:

Code: Select all

/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-21.5,-38.5}, forced=false, build_check_type=defines.build_check_type.script_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-14.5,-38.5}, forced=false, build_check_type=defines.build_check_type.script_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-7.5,-38.5}, forced=false, build_check_type=defines.build_check_type.script_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-21.5,-38.5}, forced=true, build_check_type=defines.build_check_type.script_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-14.5,-38.5}, forced=true, build_check_type=defines.build_check_type.script_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-7.5,-38.5}, forced=true, build_check_type=defines.build_check_type.script_ghost})
true
For completeness, here is the manual_ghost build types as well.

Code: Select all

/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-21.5,-38.5}, forced=false, build_check_type=defines.build_check_type.manual_ghost})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-14.5,-38.5}, forced=false, build_check_type=defines.build_check_type.manual_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-7.5,-38.5}, forced=false, build_check_type=defines.build_check_type.manual_ghost})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-21.5,-38.5}, forced=true, build_check_type=defines.build_check_type.manual_ghost})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-14.5,-38.5}, forced=true, build_check_type=defines.build_check_type.manual_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="entity-ghost", inner_name="pipe", position={-7.5,-38.5}, forced=true, build_check_type=defines.build_check_type.manual_ghost})
false
The same thing happens when you use the "blueprint_ghost" check with "pipe" entities instead of "entity-ghost":

Code: Select all

/c game.print(game.surfaces["nauvis"].can_place_entity{name="pipe", position={-21.5,-38.5}, forced=false, build_check_type=defines.build_check_type.blueprint_ghost})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="pipe", position={-14.5,-38.5}, forced=false, build_check_type=defines.build_check_type.blueprint_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="pipe", position={-7.5,-38.5}, forced=false, build_check_type=defines.build_check_type.blueprint_ghost})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="pipe", position={-21.5,-38.5}, forced=true, build_check_type=defines.build_check_type.blueprint_ghost})
false
/c game.print(game.surfaces["nauvis"].can_place_entity{name="pipe", position={-14.5,-38.5}, forced=true, build_check_type=defines.build_check_type.blueprint_ghost})
true
/c game.print(game.surfaces["nauvis"].can_place_entity{name="pipe", position={-7.5,-38.5}, forced=true, build_check_type=defines.build_check_type.blueprint_ghost})
false
Attachments
can_place_entity_test.zip
(3.67 MiB) Downloaded 2 times
My mods: Multiple Unit Train Control, RGB Pipes, Shipping Containers, Rocket Log, Smart Artillery Wagons.
Maintainer of Auto Deconstruct, Cargo Ships, Vehicle Wagon, Honk, Shortwave.
Post Reply

Return to “Modding help”