ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/maps/perl/cfplus.ext
(Generate patch)

Comparing deliantra/maps/perl/cfplus.ext (file contents):
Revision 1.1 by root, Mon Jun 12 13:23:43 2006 UTC vs.
Revision 1.8 by root, Sun Jul 30 19:57:13 2006 UTC

1#! perl 1#! perl
2 2
3# additional support for cfplus client 3# additional support for cfplus client
4 4
5use NPC_Dialogue;
6
5cf::register_extcmd cfplus_support => sub { 7cf::register_extcmd cfplus_support => sub {
6 my ($pl, $data) = @_; 8 my ($pl, $msg) = @_;
7 9
8 my ($token, $client_version) = split / /, $data, 2; 10 # $msg->{version}
9 11
10 $pl->send ("ext $token 1"); 12 (version => 1)
11}; 13};
12
13sub parse_message($) {
14 map [split /\n/, $_, 2],
15 grep length,
16 split /^\@match /m,
17 $_[0]
18}
19 14
20my %dialog; # currently active dialogs 15my %dialog; # currently active dialogs
21 16
22sub dialog_tell { 17my $timer = Event->timer (interval => 0.2, parked => 1, cb => sub {
23 my ($dialog, $msg) = @_; 18 while (my ($id, $dialog) = each %dialog) {
19 my (undef, $dx, $dy) = $dialog->{ob}->rangevector ($dialog->{npc});
20 next if (abs $dx) <= 2 && (abs $dy) <= 2;
24 21
25 my $pl = cf::player::find $dialog->{name}; 22 $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "out of range");
26 23 delete $dialog{$id};
27 for my $match (@{ $dialog->{match} }) {
28 for (split /\|/, $match->[0]) {
29 if ($_ eq "*" || 0 <= index $msg, $_) {
30 my $reply = $match->[1];
31
32 # combine lines into paragraphs
33 $reply =~ s/(?<=\S)\n(?=\w)/ /g;
34 $reply =~ s/\n\n/\n/g;
35
36 my @kw;
37 # now mark up all matching keywords
38 for my $match (@{ $dialog->{match} }) {
39 for (sort { (length $b) <=> (length $a) } split /\|/, $match->[0]) {
40 if ($reply =~ /\b\Q$_\E\b/i) {
41 push @kw, $_;
42 last;
43 }
44 }
45 }
46
47 $pl->send ("ext $dialog->{token} msg " . join "\x00", $reply, @kw);
48 return;
49 }
50 }
51 } 24 }
52 25
53 $pl->send ("ext $dialog->{token} msg ..."); 26 $_[0]->w->stop unless keys %dialog;
27});
28
29sub dialog_tell {
30 my ($id, $dialog, $msg) = @_;
31
32 my $pl = $dialog->{ob}->contr;
33 my ($reply, @kw) = $dialog->tell ($msg);
34 $reply = "..." unless $reply;
35
36 $pl->ext_reply ($id => msgtype => "reply", msg => $reply, add_topics => \@kw);
54} 37}
55 38
56# return "interesting" information about the given tile 39# return "interesting" information about the given tile
57# currently only returns the npc_dialog title when a dialog is possible 40# currently only returns the npc_dialog title when a dialog is possible
58cf::register_extcmd lookat => sub { 41cf::register_extcmd lookat => sub {
59 my ($pl, $data) = @_; 42 my ($pl, $msg) = @_;
43 my ($dx, $dy) = @$msg{qw(dx dy)};
60 44
61 my ($token, $dx, $dy) = split / /, $data; 45 my $near = (abs $dx) <= 2 && (abs $dy) <= 2;
62 46
63 my %res; 47 my %res;
64
65 my $near = abs ($dx) <= 2 && abs ($dy) <= 2;
66 48
67 if ($pl->cell_visible ($dx, $dy)) { 49 if ($pl->cell_visible ($dx, $dy)) {
68 for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) { 50 for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
69 $res{npc_dialog} = $ob->name 51 $res{npc_dialog} = $ob->name
70 if $near && $ob->message =~ /^\@match /; 52 if $near && NPC_Dialogue::has_dialogue $ob;
71 } 53 }
72 } 54 }
73 55
74 $pl->send ("ext $token " . join "\x00", %res); 56 %res
75}; 57};
76 58
77cf::register_extcmd npc_dialog_begin => sub { 59cf::register_extcmd npc_dialog_begin => sub {
78 my ($pl, $data) = @_; 60 my ($pl, $msg) = @_;
61 my ($id, $dx, $dy) = @$msg{qw(msgid dx dy)};
79 62
80 my ($token, $dx, $dy) = split / /, $data;
81
82 return unless abs ($dx) <= 2 && abs ($dy) <= 2; 63 return unless (abs $dx) <= 2 && (abs $dy) <= 2;
83 return unless $pl->cell_visible ($dx, $dy); 64 return unless $pl->cell_visible ($dx, $dy);
84 65
85 for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) { 66 for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
86 if (my @match = parse_message $npc->get_message) { 67 if (NPC_Dialogue::has_dialogue $npc) {
87 $dialog{$token} = { 68 $dialog{$id} = new NPC_Dialogue ob => $pl->ob, npc => $npc;
88 name => $pl->ob->name,
89 token => $token,
90 npc => $npc,
91 match => \@match,
92 };
93
94 dialog_tell $dialog{$token}, "hi"; 69 dialog_tell $id, $dialog{$id}, "hi";
70 $timer->start;
95 return; 71 return;
96 } 72 }
97 } 73 }
98 74
99 $pl->send ("ext $token error"); 75 (msgtype => "error", msg => "nothing to talk to found")
100}; 76};
101 77
102cf::register_extcmd npc_dialog_tell => sub { 78cf::register_extcmd npc_dialog_tell => sub {
103 my ($pl, $data) = @_; 79 my ($pl, $msg) = @_;
104 80
105 my ($token, $msg) = split / /, $data, 2; 81 dialog_tell $msg->{msgid}, $dialog{$msg->{msgid}}, $msg->{msg}
82 if $dialog{$msg->{msgid}};
106 83
107 dialog_tell $dialog{$token}, $msg 84 ()
108 if $dialog{$token};
109}; 85};
110 86
111cf::register_extcmd npc_dialog_end => sub { 87cf::register_extcmd npc_dialog_end => sub {
112 my ($pl, $token) = @_; 88 my ($pl, $msg) = @_;
113 89
114 delete $dialog{$token}; 90 delete $dialog{$msg->{msgid}};
91
92 ()
115}; 93};
116 94
95sub on_logout {
96 my ($pl, $host) = @_;
97
98 delete $dialog{$_} for grep $pl->ob == $dialog{$_}{ob}, keys %dialog;
99
100 0
101}
102
103sub on_unload {
104 while (my ($id, $dialog) = each %dialog) {
105 $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "npc dialogue module was reloaded");
106 }
107
108 %dialog = ();
109
110 0
111}
112
113

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines