Disallow player from building certain entities on certain surfaces?

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
Post Reply
blankdiploma
Burner Inserter
Burner Inserter
Posts: 11
Joined: Wed Feb 20, 2019 6:10 am
Contact:

Disallow player from building certain entities on certain surfaces?

Post by blankdiploma »

It would be fantastic to have a simple way to ban certain entities from being built on certain surfaces. Either a runtime-modifiable dictionary or a property that can be set on a surface when it's created. Either would be fine.

Maybe there's already a way to do this - something to do with defines.build_check_type.script? Can't find any documentation about how to use this, but it SOUNDS like a way to implement custom build check logic.

As a last result I suppose I could just hook on_built_entity and immediately un-build it, but that's a pretty lousy user experience compared to showing a red ghost and not allowing the placement to begin with.

User avatar
DaveMcW
Smart Inserter
Smart Inserter
Posts: 3699
Joined: Tue May 13, 2014 11:06 am
Contact:

Re: Disallow player from building certain entities on certain surfaces?

Post by DaveMcW »

You could give the surface a custom tile set with a custom collision_mask, and give the entity the same collision_mask.

Note that there are only 5 custom collision mask layers available, so there is a potential for conflict with other mods.

blankdiploma
Burner Inserter
Burner Inserter
Posts: 11
Joined: Wed Feb 20, 2019 6:10 am
Contact:

Re: Disallow player from building certain entities on certain surfaces?

Post by blankdiploma »

I could, but that seems like a fairly frivolous use of collision masks.

Checking an entity name vs. a surface-level table of banned entities during the can_build check will be MUCH cheaper than many of the other checks that already need to be performed (theoretically skipping checks against collision masks, so it should actually be faster!) and doesn't risk compatibility issues with other mods.

mrvn
Smart Inserter
Smart Inserter
Posts: 5686
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Disallow player from building certain entities on certain surfaces?

Post by mrvn »

My first thought was that there should be a check_build event that can deny the build. That way the bulk rail loader / unloader could also check for the position to be correct for train tracks. Currently it fails to build on bad coordinates by unbuilding.

Second thought was what would happen if you hold a 10000 entities blueprint and move the mouse one tile. 10000 LUA callbacks?
So at a minimum there should be only one event for a blueprint with a table of entities. Maybe with the entity names as keys and then a table of positions and directions. That way if underground belts are forbidden then the LUA script only has to check if any are present and deny them all.

The return value should be three-state: Can build, can not build and makes no sense here. The last one would be like miners in a blueprint when there is no ore in reach.

Ideally the script could even return new entities to be placed. E.g. add landfill under entities that overlap water.

blankdiploma
Burner Inserter
Burner Inserter
Posts: 11
Joined: Wed Feb 20, 2019 6:10 am
Contact:

Re: Disallow player from building certain entities on certain surfaces?

Post by blankdiploma »

Yeah, I think "give me a can_build LUA delegate" isn't going to happen, for exactly the reason you mentioned: having a 10,000 entity blueprint on the cursor and moving it around the map.

However, simply having a blacklist dictionary for "entities that can't be built on this surface" would be much more performant. It's a lot quicker to check something like that than it is to run a collision box check.

mrvn
Smart Inserter
Smart Inserter
Posts: 5686
Joined: Mon Sep 05, 2016 9:10 am
Contact:

Re: Disallow player from building certain entities on certain surfaces?

Post by mrvn »

blankdiploma wrote:
Thu Feb 21, 2019 7:50 pm
Yeah, I think "give me a can_build LUA delegate" isn't going to happen, for exactly the reason you mentioned: having a 10,000 entity blueprint on the cursor and moving it around the map.

However, simply having a blacklist dictionary for "entities that can't be built on this surface" would be much more performant. It's a lot quicker to check something like that than it is to run a collision box check.
Yes, but a single callback for a blueprint would be ok I think. Then you only check what you need to check. If all you want to do is prevent underground belts that's a single table.remove("underground-belt") call and you are done. But on the other hand if you need more checks you can do it.

Post Reply

Return to “Modding interface requests”