Page 1 of 1

Have a can_place_entity on LuaEntity itself

Posted: Mon Nov 18, 2024 7:45 pm
by hgschmie
One of the really popular mods is Picker Dollies (and its spirtual successor Even Pickier Dollies for 2.0) which allows a player to move entities around instead of destroying and recreating.

The mod works by teleporting an entity into a "safe space", then checking a target location whether the entity can "fit" in there and then teleport it back. If it would just teleport the entity into the new location, then the player could happily move entities into water, over other entities etc. teleport does no checks. :-)

The right way is to check the target position first with LuaSurface::can_place_entity. But if the mod does not move the entity away first, then, for any entity wider than a single tile, the check would always return false because the new position overlaps with the old position by a tile and therefore an entity can not be placed in the new position because it collides with itself.

The teleporting around causes a slew of other problem e.g. if teleporting around a full storage tank in 2.0 and the "safe position" by accident connects the tank to a pipe or another tank, the fluid will "leak out".

An amazing addition to the API (which would solve all these problems) would be a

Code: Select all

LuaEntity::can_place_entity { position=, direction=, force= , build_check_type=, forced= } 
that works exactly like LuaSurface::can_place_entity with name/inner_name filled out and ignores the entity itself when doing placement checking.

This would allow doing the placement check with the entity itself "in place" and there would be no need for teleporting around.

Re: Have a can_place_entity on LuaEntity itself

Posted: Tue Nov 19, 2024 8:14 am
by curiosity
Seems to me like you'd want LuaSurface::can_place_entity{entity=} instead. Who is to say you aren't supposed to move entities between surfaces?

Re: Have a can_place_entity on LuaEntity itself

Posted: Tue Nov 19, 2024 7:16 pm
by hgschmie
I think the exact details of the API will be left to the game developers. Adding an "entity=" attribute that would override/preset name, direction, position etc. would work as well.

The docs for teleport state that "Only players, cars, and spidertrons can be teleported cross-surface." and teleport creates an error if you try.

Re: Have a can_place_entity on LuaEntity itself

Posted: Tue Nov 19, 2024 7:36 pm
by Rseding91
What about an option on teleport that changes which collision check it uses for validating the teleport? Right now it does a script check which is “won’t crash the game” but it could easily be overridden to be any of the build check types . That way, the teleport would simply fail if it collided with the destination.

Re: Have a can_place_entity on LuaEntity itself

Posted: Tue Nov 19, 2024 11:36 pm
by Rseding91
I've added build_check_type to LuaControl::teleport for the next release. It will allow you to simply call teleport(...) and it will fail the teleport if the build check type fails at the destination. It automatically ignores itself for collision checks so moving half a tile to a direction won't fail the teleport like can_place_entity does for the existing entity.

Re: Have a can_place_entity on LuaEntity itself

Posted: Wed Nov 20, 2024 6:38 pm
by hgschmie
Rseding91 wrote: Tue Nov 19, 2024 11:36 pm I've added build_check_type to LuaControl::teleport for the next release. It will allow you to simply call teleport(...) and it will fail the teleport if the build check type fails at the destination. It automatically ignores itself for collision checks so moving half a tile to a direction won't fail the teleport like can_place_entity does for the existing entity.
<happy dance!> This sounds great! Looking forward to the next release to try that out. It sounds like exactly what I am looking for.

Re: Have a can_place_entity on LuaEntity itself

Posted: Thu Nov 21, 2024 9:18 pm
by hgschmie
Rseding91 wrote: Tue Nov 19, 2024 11:36 pm I've added build_check_type to LuaControl::teleport for the next release. It will allow you to simply call teleport(...) and it will fail the teleport if the build check type fails at the destination. It automatically ignores itself for collision checks so moving half a tile to a direction won't fail the teleport like can_place_entity does for the existing entity.
First, thank you for the addition! This cuts out ~ 100 lines of lua code (and frankly some pretty janky checks) from even-pickier-dollies and works great. I am doing

Code: Select all

entity.teleport(target_pos, nil, false, false, defines.build_check_type.ghost_revive)
and that seems to do the trick.

minor nits:

I used "entity.surface" for the surface parameter first and that throws an exception even though I am not teleporting between different surfaces. This was surprising (but easy to work around).

Documentation for defines.build_check_type is pretty sparse. In a twist of irony, here is the best documentation that I found and I found it by telling ChatGPT "you are an expert developer for mod for the game factorio and you have excellent knowledge of the published API. What do the different values for "defines.build_check_type" do?"

-------

In Factorio, `defines.build_check_type` is an enumeration used to specify the type of checks the game should perform when determining whether a player can build an entity at a given location. These checks are commonly used when scripting construction behavior or determining whether a building action is valid.

Here are the possible values for `defines.build_check_type` and their meanings:

### 1. `manual`
This value applies when a player manually attempts to place an entity, such as clicking with the mouse. It performs the standard checks, including collision detection, tile requirements, and other rules applicable to manual placement.

### 2. `script`
This value is used when a script places an entity programmatically. It disables some of the restrictions that apply to manual placement, such as resource availability or player-specific conditions, but still checks for valid placement in the game world.

### 3. `blueprint_ghost`
This value applies when placing blueprint ghosts, which are placeholders for entities to be built later by construction robots. It ensures that the location is valid for a ghost, but the requirements for actual resources or assembly are not enforced.

### 4. `ghost_revive`
This value is used when reviving a ghost entity, turning it from a ghost into a fully constructed entity. It performs a less strict check to ensure that the placement is valid for revival.

### 5. `script_ghost`
This is similar to `script`, but specifically applies to placement of ghost entities by a script. It checks for valid ghost placement rather than constructing the entity outright.

-------

It missed out on "manual_ghost" and I am not sure how true all the information is, but hey. Better than nothing. ;-)