Difficulties in changing AStar path mid-travel

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Solipod

Hello folks. I’ve recently started learning Godot by working on a little grid-based game. I’ve managed to adapt the AStar pathfinding in the provided demo for my own game’s structure, and it suits my needs quite well. However, there’s one aspect of the demo I can’t quite figure out how to get working:

Relevant code:

func _process(_delta):
        	if Input.is_action_just_pressed("left_click"):
        		if trying_to_move:
        			movement_interrupted = true
        		else:
        			trying_to_move = true
        			target_pos = get_global_mouse_position()
        			var path = get_parent().find_path(position, target_pos, debug_can_walk_on_water)
        			path.remove(0)
        			while not path.empty() and not movement_interrupted:
        				set_sprite_facing(as_direction(path[0] - position))
        				var func_var = do_move(path[0])
        				yield(func_var, "completed")
        				path.remove(0)
        			finish_move()
func do_move(target_pos : Vector2):
       if not movement_interrupted:
               $Tween.interpolate_property(self, "position", position, target_pos, seconds_per_step)
               $AnimationPlayer.play(walk_dir, -1, 1/seconds_per_step)
               $Tween.start()
               yield($Tween,"tween_completed")
               $AnimationPlayer.stop()
func finish_move():
	$AnimationPlayer.play(idle_dir)
	trying_to_move = false
	movement_interrupted = false

While this isn’t entirely undesirable behaviour, as the title suggests I’m looking to accomplish something similar to the AStar demo in which instead of being cancelled, the destination is changed and the character paths to the new point instead. However, as the demo’s movement is a bit different from mine (notably in that it doesn’t use a Tween), I haven’t quite been able to implement it in my own game.

With some small adjustments, I was able to get it slightly closer to the desired behaviour, but…

Relevant code:

func _process(_delta)
        if Input.is_action_just_pressed("left_click"):
        			if trying_to_move:
        				movement_interrupted = true
        			trying_to_move = true
        			target_pos = get_global_mouse_position()
        		    var path = get_parent().find_path(position, target_pos, debug_can_walk_on_water)
        			if not path.empty(): path.remove(0)
        
        			while not path.empty():
        				set_sprite_facing(as_direction(path[0] - position))
        				if movement_interrupted:
        					break
        				var func_var = do_move(path[0])
        				if func_var is GDScriptFunctionState: yield(func_var, "completed")
        				
        				path.remove(0)
        			finish_move()

    (do_move and finish_move same as above)

While the character ends up in the correct place, this obviously looks horrible, and it steps over multiple cells at once. I feel like the root of the problem is the Tween but I’m at quite a loss as to how I can fix it up from here. Hopefully I’ve provided enough information to get some feedback, and if not, I’ll do my best to explain.

Any input is much appreciated, as I’m still quite unfamiliar with the node-based structure of Godot, so my approach may be completely off the mark.