Page 1 of 1
[1.1.53] find_non_colliding_position returns colliding position
Posted: Sat Feb 12, 2022 9:42 am
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.
Re: [1.1.53] find_non_colliding_position returns colliding position
Posted: Sat Feb 12, 2022 11:55 am
by Klonan
Can you provide a specific script or set up to test?
Re: [1.1.53] find_non_colliding_position returns colliding position
Posted: Sun Feb 13, 2022 4:40 pm
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.
Re: [1.1.53] find_non_colliding_position returns colliding position
Posted: Mon Feb 14, 2022 9:46 am
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.
Re: [1.1.53] find_non_colliding_position returns colliding position
Posted: Mon Feb 14, 2022 5:44 pm
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.