[1.1.53] find_non_colliding_position returns colliding position

Bugs that we were not able to reproduce, and/or are waiting for more detailed info.
SilentStorm
Inserter
Inserter
Posts: 27
Joined: Sun Jul 09, 2017 9:19 am
Contact:

[1.1.53] find_non_colliding_position returns colliding position

Post by SilentStorm »

calling

Code: Select all

game.player.surface.find_non_colliding_position('car', game.player.position, 10, 1)
returns a position that will collide with the car, as evidenced by teleporting the car to the returned location, then attempting to move the car, which won't move.
When using a precision of 2 it works, in that I have not seen the returned position being invalid.
The same can also be seen when using 'character' instead of 'car' with a precision value of 0.5, which also causes the returned position to be invalid. This can no longer be observed (in my experience) when using 1 as a precision value instead.

This happens most frequently with cliffs, but with the character I have also observed it with rocks.

According to the function name and the description the function is supposed to take into account the collision box of the prototype specified, but this does not seem to be working correctly sometimes.
User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5266
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: [1.1.53] find_non_colliding_position returns colliding position

Post by Klonan »

Can you provide a specific script or set up to test?
robot256
Filter Inserter
Filter Inserter
Posts: 874
Joined: Sun Mar 17, 2019 1:52 am
Contact:

Re: [1.1.53] find_non_colliding_position returns colliding position

Post by robot256 »

I seem to recall that it might only check the prototype collision box in orientation=0. If the car you are teleporting is rectangular and rotated, it might not fit quite right.
User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2971
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: [1.1.53] find_non_colliding_position returns colliding position

Post by boskid »

I was unable to find any issues with that function given provided details. Easiest catch here is that indeed this function uses a non rotated collision box from the prototype so if it finds a position which does not collide with non rotated car, it is not guaranteed it will not collide with rotated car. Any feature requests here (like a bounding box expansion, usage of specified orientation, providing a specific entity so it uses real collision box of existing entity) will make this a modding interface request.
SilentStorm
Inserter
Inserter
Posts: 27
Joined: Sun Jul 09, 2017 9:19 am
Contact:

Re: [1.1.53] find_non_colliding_position returns colliding position

Post by SilentStorm »

basically I have been doing the following for some time. Eventually you will find a place that is claimed as being a valid position, you will be teleported and unable to move. This might put you at the edge of spawners, barely inside a cliff or into a rock.

Code: Select all

local function getRandomPositionInDistance(pos, distance)
  -- inspired by stdlib::Position
  local direction = math.random(0, 360)
  local x = math.sin(direction) * distance
  local y = math.cos(direction) * distance
  x = pos.x + (math.random() < 0.5 and x or x * -1)
  y = pos.y + (math.random() < 0.5 and y or y * -1)
  return {x=x, y=y}
end

local function teleport()
  local distance = math.random(20, 100)
  local randomPosition = getRandomPositionInDistance(game.player.position, distance)
  if not game.player.surface.can_place_entity{name=game.player.character.prototype.name, position = randomPosition, force = game.player.force} then
    local safePosition = game.player.surface.find_non_colliding_position(game.player.character.prototype.name, randomPosition, 10, 0.5)
    if safePosition then
      game.player.teleport(safePosition, game.player.surface)
    else
      game.print('No location found for teleportation around [gps=' .. math.floor(randomPosition.x + 0.5) .. ',' .. math.floor(randomPosition.y + 0.5) .. ']. Better luck next time')
    end
  else
    game.player.teleport(randomPosition, game.player.surface)
  end
end

script.on_nth_tick(300, teleport)
I eventually ended up just using 1 as the step (instead of the 0.5 above), which so far has prevented the issue from manifesting itself. So it might be due to the orientation of the actual entity, as basically I did double what the collision box says it should be, which would pretty much cover every possible orientation of the entity.
Post Reply

Return to “Pending”