--- deliantra/server/ext/cfplus.ext 2006/12/15 19:29:18 1.1 +++ deliantra/server/ext/cfplus.ext 2007/06/19 17:32:56 1.6 @@ -25,27 +25,15 @@ # $msg->{version} - (version => 2) + ( + version => 2, + ) }; -my %dialog; # currently active dialogs - -my $timer = Event->timer (interval => 0.2, parked => 1, data => cf::WF_AUTOCANCEL, cb => sub { - while (my ($id, $dialog) = each %dialog) { - my (undef, $dx, $dy) = $dialog->{ob}->rangevector ($dialog->{npc}); - next if (abs $dx) <= 2 && (abs $dy) <= 2; - - $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "out of range"); - delete $dialog{$id}; - } - - $_[0]->w->stop unless keys %dialog; -}); - sub dialog_tell { my ($id, $dialog, $msg) = @_; - my $pl = $dialog->{ob}->contr; + my $pl = $dialog->{pl}; my ($reply, @kw) = $dialog->tell ($msg); $reply = "..." unless $reply; @@ -68,6 +56,8 @@ my ($pl, $msg) = @_; my ($dx, $dy) = @$msg{qw(dx dy)}; + return unless $pl->ob && $pl->ob->map; + my $near = (abs $dx) <= 2 && (abs $dy) <= 2; my %res; @@ -75,7 +65,7 @@ if ($pl->cell_visible ($dx, $dy)) { for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) { $res{npc_dialog} = $ob->name - if $near && NPC_Dialogue::has_dialogue $ob; + if $near && NPC_Dialogue::has_dialogue $ob && !$pl->{npc_dialog}; } } @@ -89,7 +79,7 @@ messages related to this dialog interaction. It either replies with an error reply or starts a dialog by telling -the npc "hi" and returning a reply strcuture as with C. =cut @@ -98,14 +88,16 @@ my ($pl, $msg) = @_; my ($id, $dx, $dy) = @$msg{qw(msgid dx dy)}; + return unless $pl->ob && $pl->ob->map; return unless (abs $dx) <= 2 && (abs $dy) <= 2; return unless $pl->cell_visible ($dx, $dy); + return if $pl->{npc_dialog}; # only one dialog at a time for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) { if (NPC_Dialogue::has_dialogue $npc) { - $dialog{$id} = new NPC_Dialogue ob => $pl->ob, npc => $npc; - dialog_tell $id, $dialog{$id}, "hi"; - $timer->start; + $pl->attach ("npc_dialog_active"); + $pl->{npc_dialog} = new NPC_Dialogue pl => $pl, npc => $npc, id => $id; + dialog_tell $id, $pl->{npc_dialog}, "hi"; return; } } @@ -128,8 +120,9 @@ cf::register_extcmd npc_dialog_tell => sub { my ($pl, $msg) = @_; - dialog_tell $msg->{msgid}, $dialog{$msg->{msgid}}, $msg->{msg} - if $dialog{$msg->{msgid}}; + if (my $dialog = $pl->{npc_dialog}) { + dialog_tell $msg->{msgid}, $dialog, $msg->{msg}; + } () }; @@ -143,19 +136,13 @@ cf::register_extcmd npc_dialog_end => sub { my ($pl, $msg) = @_; - delete $dialog{$msg->{msgid}}; + if (my $dialog = delete $pl->{npc_dialog}) { + $pl->detach ("ncpa_dialog_active"); + } () }; -cf::attach_to_players - on_logout => sub { - my ($pl) = @_; - - delete $dialog{$_} for grep $pl->ob == $dialog{$_}{ob}, keys %dialog; - }, -; - =item ... = extcmd editor_support Returns the value required by clients that have an editor to download and @@ -191,13 +178,51 @@ }; sub unload { - while (my ($id, $dialog) = each %dialog) { - $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "npc dialogue module was reloaded"); + for my $pl (cf::player::list) { + if (my $dialog = delete $pl->{npc_dialog}) { + $pl->detach ("npc_dialog_active"); + $pl->ext_reply ($dialog->{id} => msgtype => "error", msg => "npc dialogue module was reloaded"); + } } - - %dialog = (); } +cf::player::attachment npc_dialog_active => + on_logout => sub { + my ($pl) = @_; + + delete $pl->{npc_dialog}; + $pl->detach ("npc_dialog_active"); + }, + on_move => sub { + my ($pl, $dir) = @_; + + if (my $dialog = $pl->{npc_dialog}) { + warn "on_move<@_>\n";#d# + warn $pl->ob; + warn $dialog; + warn $dialog->{npc}; + warn $dialog->{npc}->is_valid; + + my (undef, $dx, $dy) = $pl->ob->rangevector ($dialog->{npc}); + + return if (abs $dx) <= 2 && (abs $dy) <= 2; + + $pl->ext_reply ($dialog->{id} => msgtype => "error", msg => "out of range"); + } + + delete $pl->{npc_dialog}; + $pl->detach ("npc_dialog_active"); + }, +; + +cf::player->attach ( + on_login => sub { + my ($pl) = @_; + + delete $pl->{npc_dialog}; + }, +); + =back =cut