--- deliantra/server/ext/cfplus.ext 2007/04/02 18:04:45 1.4 +++ deliantra/server/ext/cfplus.ext 2007/06/16 14:35:41 1.5 @@ -30,24 +30,10 @@ ) }; -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; @@ -79,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}; } } @@ -93,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 @@ -105,12 +91,13 @@ 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; + dialog_tell $id, $pl->{npc_dialog}, "hi"; return; } } @@ -133,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}; + } () }; @@ -148,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::player->attach ( - 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 @@ -196,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