You might want consider not using Yield. I find yield is a bit dangerous, because it can make the game hang or feel unresponsive.
Instead of yield, you could connect the "tweenallcompleted" signal to onplayertimeadvanced and check if time < movecost, then notify the player script.
e.g. NPC:
var path = []
var time #This stores how much time this character has to act.
var destination
var animator = getnodeornull("Path to a tween node")
func onplayertimeadvanced(time):
#Code to determine cost of next move.
if time >= movecost:
var nextmove = path.popback()
time -= movecost
animator.interpolateproperty(self, "position", null, nextmove, ...)
animator.start()
connect("tweenallcompleted", self, "onplayertimeadvanced", time)
else:
disconnect("tweenallcompleted", self, "onplayertimeadvanced")
gettree().callgroup("Player", "DoNextMove - or whatever")
and then in player:
var path = [] #This contains the series of moves.
var destination #The final point in the path.
var animator = getnodeornull("Path to a tween node")
signal timeadvanced(time)
func DoTheMove():
if player.position != destination:
var nextmove = path.popback()
#Some code to determine the time taken in the next move.
emitsignal("timeadvanced", time)
animator.interpolateproperty(player, "position", null, nextmove, ...)
animator.start()
connect("tweenallcompleted", self, "DoTheMove")
else:
disconnect("tweenallcompleted", self, "DoTheMove")
In this case you'd add the player to a group called "Player"
You might want to consider using groups instead of signals
This is a different design pattern... I'm not sure while loops and yields are the best choice here (although I could be totally wrong! I don't know your situation).
Another option to consider...Are you familiar with Global Event Bus design patterns?