--- deliantra/server/ext/follow.ext 2010/05/18 21:30:16 1.21 +++ deliantra/server/ext/follow.ext 2010/05/18 21:45:37 1.22 @@ -7,12 +7,13 @@ # don't follow on damned ground our $MAX_QUEUE = 5; # the # of positions somebody else can lead -our %follow; # $followername => [$follower, $target, [$queue]] +our %FOLLOW; # $followername => [$follower, $target, [$queue]] +our $FOLLOW_HANDLER; sub unfollow($) { my $name = shift; - if (my $f = delete $follow{$name}) { + if (my $f = delete $FOLLOW{$name}) { my ($who, $target, undef) = @$f; $who->contr->detach ("follow_aborter"); $target->message ("$name no longer follows you."); @@ -31,50 +32,54 @@ }, ; -our $CORO = cf::async { - $Coro::current->{desc} = "follow handler"; - - while () { - cf::wait_for_tick; - - for (values %follow) { - my ($who, $target, $queue) = @$_; - - my ($map, $x, $y) = ($target->map, $target->x, $target->y); - - # add new position to queue, if any - push @$queue, [$map, $x, $y] - if $map != $queue->[-1][0] - || $x != $queue->[-1][1] - || $y != $queue->[-1][2]; - - # try to move to oldest position - if (@$queue > $MAX_QUEUE) { - $who->message ($target->name . " is too far away - you can't follow anymore!"); - unfollow $target->name; - } else { - my ($map, $x, $y) = @{ $queue->[0] }; - - $map->load; - - if ( - !$map->valid - or $map->path !~ /^(\{link\}|\/)/ - or grep $_->flag (cf::FLAG_IS_FLOOR) && ($_->flag (cf::FLAG_UNIQUE) || $_->type == cf::SHOP_FLOOR), - $map->at ($x, $y)) - ) { - $who->message ("You can't follow " . $target->name . " anymore!"); - unfollow $who->name; - } elsif (!$who->blocked ($map, $x, $y)) { - shift @$queue; - $who->goto ($map, $x, $y); +sub start_follow_handler { + $FOLLOW_HANDLER = cf::async_ext { + $Coro::current->{desc} = "follow handler"; + + while () { + cf::wait_for_tick; + + for (values %FOLLOW) { + my ($who, $target, $queue) = @$_; + + my ($map, $x, $y) = ($target->map, $target->x, $target->y); + + # add new position to queue, if any + push @$queue, [$map, $x, $y] + if $map != $queue->[-1][0] + || $x != $queue->[-1][1] + || $y != $queue->[-1][2]; + + # try to move to oldest position + if (@$queue > $MAX_QUEUE) { + $who->message ($target->name . " is too far away - you can't follow anymore!"); + unfollow $target->name; + } else { + my ($map, $x, $y) = @{ $queue->[0] }; + + $map->load; + + if ( + !$map->valid + or $map->path !~ /^(\{link\}|\/)/ + or grep $_->flag (cf::FLAG_IS_FLOOR) && ($_->flag (cf::FLAG_UNIQUE) || $_->type == cf::SHOP_FLOOR), + $map->at ($x, $y) + ) { + $who->message ("You can't follow " . $target->name . " anymore!"); + unfollow $who->name; + } elsif (!$who->blocked ($map, $x, $y)) { + shift @$queue; + $who->goto ($map, $x, $y); + } } } + + Coro::schedule unless keys %FOLLOW; } + }; +} - Coro::schedule unless keys %follow; - } -}; +start_follow_handler; cf::register_command follow => sub { my ($who, $args) = @_; @@ -91,24 +96,24 @@ ) { $who->message ("Following player '$args', to stop, type: 'follow"); $other->message ("$name is now following your every step..."); - $follow{$name} = [ + $FOLLOW{$name} = [ $who, $other, [[$other->map, $other->x, $other->y]], ]; $who->contr->attach ("follow_aborter"); - $CORO->ready; + $FOLLOW_HANDLER->ready; } else { $who->message ("You must stand directly beside '$args' to follow her/him"); - delete $follow{$name}; + delete $FOLLOW{$name}; } } else { $who->message ("Cannot follow '$args': no such player"); - delete $follow{$name}; + delete $FOLLOW{$name}; } } else { $who->message ("follow mode off"); - delete $follow{$name}; + delete $FOLLOW{$name}; } }; @@ -119,7 +124,7 @@ unfollow $name; - while (my ($k, $v) = each %follow) { + while (my ($k, $v) = each %FOLLOW) { unfollow $k if $v->[1]->name eq $name; }