How do I use request_path?
Posted: Thu Feb 09, 2023 5:50 am
I'm trying to make a simple mod where the character walks to wherever I click on the map. I'm using request_path for pathfinding, but it keeps giving me paths through things that the character can't walk through, like in this screenshot:
Also, some of the paths seem to go the long way to reach the destinations, rather than taking more direct routes. What I'm getting hung up on is this field collision_mask that I'm supposed to pass to request_path. I'm not sure what values to use. None of the combinations I've tried have worked.
Here is my code:
Does anyone have an idea as to why this does not work?
Also, some of the paths seem to go the long way to reach the destinations, rather than taking more direct routes. What I'm getting hung up on is this field collision_mask that I'm supposed to pass to request_path. I'm not sure what values to use. None of the combinations I've tried have worked.
Here is my code:
Code: Select all
character_is_moving = false
path_index = 1
path = nil
-- Determines which direction the character should go.
local function get_direction(start_position, end_position)
local angle = math.atan2(end_position.y - start_position.y, start_position.x - end_position.x)
-- Given a circle representing the angles, it is divided into eight octants representing the cardinal directions.
local octant = (angle + math.pi) / (2 * math.pi) * 8 + 0.5
if octant < 1 then
return defines.direction.east
elseif octant < 2 then
return defines.direction.northeast
elseif octant < 3 then
return defines.direction.north
elseif octant < 4 then
return defines.direction.northwest
elseif octant < 5 then
return defines.direction.west
elseif octant < 6 then
return defines.direction.southwest
elseif octant < 7 then
return defines.direction.south
else
return defines.direction.southeast
end
end
function positions_approximately_equal(a, b)
return math.abs(a.x - b.x) < 0.25 and math.abs(a.y - b.y) < 0.25
end
-- Requests a path when the map is clicked.
script.on_event("mouse-click", function (event)
local surface = game.get_surface("nauvis")
local character = game.get_player(1).character
surface.request_path{
bounding_box = character.bounding_box,
collision_mask = character.prototype.collision_mask,
start = character.position,
goal = event.cursor_position,
force = "player"
}
end)
-- Initializes the movement process when the path is received.
script.on_event(defines.events.on_script_path_request_finished, function (event)
character_is_moving = true
path = event.path
path_index = 1
end)
-- Moves the character.
script.on_event(defines.events.on_tick, function (event)
local character = game.get_player(1).character
if character_is_moving and path ~= nil then
if positions_approximately_equal(character.position, path[path_index].position) then
-- waypoint reached
path_index = path_index + 1 -- select the next waypoint
end
if path_index == #path then
character_is_moving = false
path_index = 1
else
-- move the character for one tick
game.get_player(1).walking_state = {
walking = true,
direction = get_direction(character.position, path[path_index].position)
}
end
end
end)