Get entity size

Place to get help with not working mods / modding interface.
User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2905
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Get entity size

Post by darkfrei »

How correctly get entity size?


So looks entities 1x1:

Code: Select all

collision_box = {{-0.15, -0.15}, {0.15, 0.15}}
collision_box = {{-0.29, -0.29}, {0.29, 0.29}}
collision_box = {{-0.35, -0.35}, {0.35, 0.35}}
collision_box = {{-0.4, -0.4}, {0.4, 0.4}}
So looks entities 2x1:

Code: Select all

collision_box = {{-0.6, -0.45}, {0.6, 0.3}}
So looks entities 1x2:

Code: Select all

collision_box = {{-0.4, -0.9}, {0.4, 0.9}}
So looks entities 2x2:

Code: Select all

collision_box = {{-0.65, -0.65}, {0.65, 0.65}}
collision_box = {{-0.7, -0.7}, {0.7, 0.7}}
collision_box = {{-0.9, -0.9}, {0.9, 0.9}}
So looks entities 3x2:

Code: Select all

collision_box = {{-1.29, -0.79}, {1.29, 0.79}}
So looks entities 3x3:

Code: Select all

collision_box = {{-1.2, -1.2}, {1.2, 1.2}}
collision_box = {{-1.4, -1.4}, {1.4, 1.4}}
So looks entities 3x5:

Code: Select all

collision_box = {{-1.35, -2.35}, {1.35, 2.35}}
So looks entities 5x5:

Code: Select all

collision_box = {{-2.4, -2.4}, {2.4, 2.4}}
Bilka
Factorio Staff
Factorio Staff
Posts: 3310
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Get entity size

Post by Bilka »

Use the selection box, it's usually more accurate
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Get entity size

Post by eradicator »

Just calculate the dimensions of the collision box. i.e.:

collision_box = {{-1.29, -0.79}, {1.29, 0.79}} means:
width is |-1.29| + |1.29| = 2.58, height is 1.58. Now check agsinst nearest integer.
2.58 < 3, so it's centered over 3 tiles, 1.58 < 2, so centered over two tiles. Do note that the correct operation here is "<" and not "<=", i.e. if an entity has a side length of 2.00 that is NOT smaller than 2 and thus will be centered over 3 tiles., whereas 1.99 would be centered over two tiles.

Also note that the centering does not affect the size of an entity. a {{-0.5,-0.5},{0.5,0.5}} will be centered in the middle of a 2x2 tile area, but it will still only "block" (=collide) in a one square tile area, so most of the 2x2 area would be buildable if you had anything small enough to fit :P.

But without knowing what you actually wanted to do i can't say anymore.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2905
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Get entity size

Post by darkfrei »

I need the entity size for automatically placing of pipe connections. If entity is 3x5, then it can be much easy to set right positions than with collision box like {{-1.25, -2.4}, {1.25, 2.4}}
chrisgbk
Long Handed Inserter
Long Handed Inserter
Posts: 93
Joined: Mon Jan 02, 2017 4:31 am
Contact:

Re: Get entity size

Post by chrisgbk »

darkfrei wrote:I need the entity size for automatically placing of pipe connections. If entity is 3x5, then it can be much easy to set right positions than with collision box like {{-1.25, -2.4}, {1.25, 2.4}}
Assuming eradicator's post is correct:

Code: Select all

local tilewidth = math.floor(collision_box and (collision_box[2][1] - collision_box[1][1]) or 0) + 1
local tileheight = math.floor(collision_box and (collision_box[2][2] - collision_box[1][2]) or 0) + 1
Will result in, for the collision boxes you provided in order:

Code: Select all

1	1
1	1
1	1
1	1
2	1
1	2
2	2
2	2
2	2
3	2
3	3
3	3
3	5
5	5
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Get entity size

Post by eradicator »

@chrisgbk:
That's a nice and short way to do it. But i think technically there's no restriction for the box to be {left-top,right-bottom}, so you'd need to include some math.abs in case someone goes crazy and has {right-top,left-bottom} or something (this statement is wrong until proven right :P).

But @darkfrei has an even bigger problem for automatically fiddling with fluid boxes, which is unsymmetric collision boxes. {{-1, -0.5},{3.1, 4.5}} is perfectly valid, but not centered on 0,0. So depending on whatever he wants to do he needs to calculate left-width, right-width, top-heigh, bottom-height.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
chrisgbk
Long Handed Inserter
Long Handed Inserter
Posts: 93
Joined: Mon Jan 02, 2017 4:31 am
Contact:

Re: Get entity size

Post by chrisgbk »

eradicator wrote:@chrisgbk:
That's a nice and short way to do it. But i think technically there's no restriction for the box to be {left-top,right-bottom}, so you'd need to include some math.abs in case someone goes crazy and has {right-top,left-bottom} or something (this statement is wrong until proven right :P).
http://lua-api.factorio.com/latest/Conc ... oundingBox specifies the order. Whether or not this order is enforced with a consistency check or silently fixed internally if the bounding box has a negative width/height is another matter - but that can be solved by explicitly using collision_box.left_top and collision_box.right_bottom.
But @darkfrei has an even bigger problem for automatically fiddling with fluid boxes, which is unsymmetric collision boxes. {{-1, -0.5},{3.1, 4.5}} is perfectly valid, but not centered on 0,0. So depending on whatever he wants to do he needs to calculate left-width, right-width, top-heigh, bottom-height.
I would say he just needs to calculate the center:

Code: Select all

centerx = (collision_box[1][1] + collision_box[2][1])/2
centery = (collision_box[1][2] + collision_box[2][2])/2
then convert that to a tile index, and use that. But by that point it probably will have been easier to just learn to use the collision boxes as they exist, because I'm pretty sure you inevitably end up deriving them again indirectly going this route.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Get entity size

Post by eradicator »

@chrisgbk:
I doubt the center would be of any use as the fluid box specifications are most likely offsets of the position (i.e. 0,0) and not the center of an entity. And that position can't be derived from the width/height and center/center values.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
chrisgbk
Long Handed Inserter
Long Handed Inserter
Posts: 93
Joined: Mon Jan 02, 2017 4:31 am
Contact:

Re: Get entity size

Post by chrisgbk »

eradicator wrote:@chrisgbk:
I doubt the center would be of any use as the fluid box specifications are most likely offsets of the position (i.e. 0,0) and not the center of an entity. And that position can't be derived from the width/height and center/center values.
The position 0,0 can be calculated with a translation. If a bounding box is symmetrical, the calculated center is 0,0, if it's asymetrical, the calculated center will be non-zero, but a translation of -center.x, -center.y takes you to 0,0

I haven't specifically checked an entity with a non-symmetrical collision box with fluids, because none exist in vanilla and I haven't created one for testing yet. So I don't yet have the exact formulas worked out - it's on my todo list.

I'm working on a tool that deals with these kinds of things; an external tool to factorio that parses data.raw and allows visual inspection(and setting) of the entity properties, for example, the vanilla boiler:

Image

An explanation of the boxes:
  • Gray is the entity image.
  • Maroon is the collision box.
  • Black is the calculated tile footprint from the collision box.
  • Lime is the allowed area that pipe_connections are allowed to be in based on the code provided by Rseding91 and assuming that the boundingBox used in this check is the collision_box and not a derived tile footprint boundingBox.
  • Green X's are the input-output pipe_connections.
  • Blue X is the output pipe_connection.
Since I intend it to be mod compatible, I have to work out the exact behaviour in Factorio for non-symmetrical boxes and replicate it, so I'll have a definitive answer when I get around to doing that.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Get entity size

Post by eradicator »

@chrisgbk
That sounds quite useful indeed (and like a huge amount of work). There's been a few people over the years to attempt a proper sprite management tool (scale, shift, fluidbox, circuit connection point/graphic, inserter positions, rotation, etc) but as far as i know nobody ever came to a final release. From personal experience getting that part of a new entity prototype right is definetly the most annoying part currently as it involves tons of trial & error to get the shit right and easily costs 80% of the effort/time. Especially as there's next to no documentation and the games error messages regarding this are mostly useless (e.g. "some part of the fluidbox definition is wrong!" bleh...but WHAT PART /ragequit ^_^). I really wonder how wube does it internally..., they must have automated it by now...

PS: Feel free me to pm me if you run into any roadblocks regarding that tool ^^.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
chrisgbk
Long Handed Inserter
Long Handed Inserter
Posts: 93
Joined: Mon Jan 02, 2017 4:31 am
Contact:

Re: Get entity size

Post by chrisgbk »

eradicator wrote:@chrisgbk
That sounds quite useful indeed (and like a huge amount of work). There's been a few people over the years to attempt a proper sprite management tool (scale, shift, fluidbox, circuit connection point/graphic, inserter positions, rotation, etc) but as far as i know nobody ever came to a final release. From personal experience getting that part of a new entity prototype right is definetly the most annoying part currently as it involves tons of trial & error to get the shit right and easily costs 80% of the effort/time. Especially as there's next to no documentation and the games error messages regarding this are mostly useless (e.g. "some part of the fluidbox definition is wrong!" bleh...but WHAT PART /ragequit ^_^). I really wonder how wube does it internally..., they must have automated it by now...

PS: Feel free me to pm me if you run into any roadblocks regarding that tool ^^.
It's not that difficult, it's just coordinate translations.

Asymmetrical collision boxes supported now.

Code: Select all

require("util")

-- copy from base prototypes
local entity = table.deepcopy(data.raw["boiler"]["boiler"])
local item = table.deepcopy(data.raw["item"]["boiler"])
local recipe = table.deepcopy(data.raw["recipe"]["boiler"])

entity.name = "custom-boiler"
entity.minable.result = "custom-boiler"
entity.collision_box = {
        {
          -0.79,
          -0.79000000000000004
        },
        {
          1.79,
          0.79000000000000004
        }
      }
      
entity.fluid_box.pipe_connections = {
          {
            position = {
              -1.5,
              0.5
            },
            type = "input-output"
          },
          {
            position = {
              2.5,
              0.5
            },
            type = "input-output"
          }
        }

item.name = "custom-boiler"
item.place_result = "custom-boiler"

recipe.name = "custom-boiler"
recipe.result = "custom-boiler"
recipe.enabled = true --laziness for testing

data:extend{entity, item, recipe}
Image

Which matches in-game entity behaviour (except I still have to do the drawing of pipe covers).

Image

Apparently it's possible for the footprint of an entity to take up 4 tiles when it's <3 tiles wide in certain cases, so it took a lil bit of time to work that out.
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Get entity size

Post by eradicator »

chrisgbk wrote:It's not that difficult, it's just coordinate translations.
I shall be looking forward for the finished program then ;)
chrisgbk wrote:Apparently it's possible for the footprint of an entity to take up 4 tiles when it's <3 tiles wide in certain cases, so it took a lil bit of time to work that out.
I have no clue how factorio internally centers entities with assymetrical collision boxes. "Theoretically" anything with >2.0 width could be centered on the edge between the tiles and thus look like it occupies 4 tiles. (Btw there's no rule against two entities being in the same tile as long as their collision boxes fit.)
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
User avatar
moon69
Fast Inserter
Fast Inserter
Posts: 183
Joined: Sun Sep 18, 2016 6:53 pm
Contact:

Re: Get entity size

Post by moon69 »

chrisgbk wrote: Sat Jan 06, 2018 3:42 pm I'm working on a tool that deals with these kinds of things; an external tool to factorio that parses data.raw and allows visual inspection(and setting) of the entity properties, for example, the vanilla boiler:
Did your tool come to fruition?

I'm particularly interested in your findings on this...
chrisgbk wrote: Sat Jan 06, 2018 3:42 pm Since I intend it to be mod compatible, I have to work out the exact behaviour in Factorio for non-symmetrical boxes and replicate it, so I'll have a definitive answer when I get around to doing that.
User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2905
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Get entity size

Post by darkfrei »

Code:

Code: Select all

  local cb = entity.collision_box
  local min_x = math.floor (cb[1][1]*2)/2 -- -0.4 --> -0.5; -1.4 --> -1.5; 
  local min_y = math.floor (cb[1][2]*2)/2
  
  local max_x = math.ceil (cb[2][1]*2)/2
  local max_y = math.ceil (cb[2][2]*2)/2
  
  local entity_size = (max_x-min_x) .. 'x' .. (max_y-min_y)
  
  log (entity.name .. ' size: ' .. entity_size)
Result:

Code: Select all

stone-furnace size: 2x2
electric-furnace size: 3x3
steel-furnace size: 2x2
assembling-machine-1 size: 3x3
assembling-machine-2 size: 3x3
assembling-machine-3 size: 3x3
oil-refinery size: 5x5
chemical-plant size: 3x3
centrifuge size: 3x3
electric-mining-drill size: 3x3
burner-mining-drill size: 2x2
pumpjack size: 3x3
lab size: 3x3
Post Reply

Return to “Modding help”