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.2 by root, Mon Jun 12 14:13:39 2006 UTC vs.
Revision 1.3 by root, Mon Jun 19 10:15:10 2006 UTC

8 my ($token, $client_version) = split / /, $data, 2; 8 my ($token, $client_version) = split / /, $data, 2;
9 9
10 $pl->send ("ext $token 1"); 10 $pl->send ("ext $token 1");
11}; 11};
12 12
13{
14 package NPC_Dialogue;
15
16 sub has_dialogue {
17 my ($ob) = @_;
18
19 $ob->get_message =~ /^\@match /;
20 }
21
13sub parse_message($) { 22 sub parse_message($) {
14 map [split /\n/, $_, 2], 23 map [split /\n/, $_, 2],
15 grep length, 24 grep length,
16 split /^\@match /m, 25 split /^\@match /m,
17 $_[0] 26 $_[0]
27 }
28
29 sub new {
30 my ($class, %arg) = @_;
31
32 my $self = bless {
33 %arg,
34 }, $class;
35
36 $self->{match} ||= [parse_message $self->{npc}->get_message];
37
38 $self;
39 }
40
41 sub greet {
42 my ($self) = @_;
43
44 $self->tell ("hi")
45 }
46
47 sub tell {
48 my ($self, $msg) = @_;
49
50 for my $match (@{ $self->{match} }) {
51 for (split /\|/, $match->[0]) {
52 if ($_ eq "*" || 0 <= index $msg, $_) {
53 my $reply = $match->[1];
54
55 # combine lines into paragraphs
56 $reply =~ s/(?<=\S)\n(?=\w)/ /g;
57 $reply =~ s/\n\n/\n/g;
58
59 my @kw;
60 # now mark up all matching keywords
61 for my $match (@{ $self->{match} }) {
62 for (sort { (length $b) <=> (length $a) } split /\|/, $match->[0]) {
63 if ($reply =~ /\b\Q$_\E\b/i) {
64 push @kw, $_;
65 last;
66 }
67 }
68 }
69
70 return wantarray ? ($reply, @kw) : $reply;
71 }
72 }
73 }
74 }
75
76 ()
18} 77}
19 78
20my %dialog; # currently active dialogs 79my %dialog; # currently active dialogs
21 80
22sub dialog_tell { 81sub dialog_tell {
23 my ($dialog, $msg) = @_; 82 my ($token, $dialog, $msg) = @_;
24 83
25 my $pl = cf::player::find $dialog->{name}; 84 my $pl = $dialog->{ob}->contr;
26 85 my ($reply, @kw) = $dialog->tell ($msg);
27 for my $match (@{ $dialog->{match} }) { 86 $reply = "..." unless $reply;
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); 87 $pl->send ("ext $token msg " . join "\x00", $reply, @kw);
48 return;
49 }
50 }
51 }
52
53 $pl->send ("ext $dialog->{token} msg ...");
54} 88}
55 89
56# return "interesting" information about the given tile 90# return "interesting" information about the given tile
57# currently only returns the npc_dialog title when a dialog is possible 91# currently only returns the npc_dialog title when a dialog is possible
58cf::register_extcmd lookat => sub { 92cf::register_extcmd lookat => sub {
59 my ($pl, $data) = @_; 93 my ($pl, $data) = @_;
60 94
61 my ($token, $dx, $dy) = split / /, $data; 95 my ($token, $dx, $dy) = split / /, $data;
96 my $near = (abs $dx) <= 2 && (abs $dy) <= 2;
62 97
63 my %res; 98 my %res;
64
65 my $near = (abs $dx) <= 2 && (abs $dy) <= 2;
66 99
67 if ($pl->cell_visible ($dx, $dy)) { 100 if ($pl->cell_visible ($dx, $dy)) {
68 for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) { 101 for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
69 $res{npc_dialog} = $ob->name 102 $res{npc_dialog} = $ob->name
70 if $near && $ob->message =~ /^\@match /; 103 if $near && NPC_Dialogue::has_dialogue $ob;
71 } 104 }
72 } 105 }
73 106
74 $pl->send ("ext $token " . join "\x00", %res); 107 $pl->send ("ext $token " . join "\x00", %res);
75}; 108};
81 114
82 return unless (abs $dx) <= 2 && (abs $dy) <= 2; 115 return unless (abs $dx) <= 2 && (abs $dy) <= 2;
83 return unless $pl->cell_visible ($dx, $dy); 116 return unless $pl->cell_visible ($dx, $dy);
84 117
85 for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) { 118 for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
86 if (my @match = parse_message $npc->get_message) { 119 if (NPC_Dialogue::has_dialogue $npc) {
87 $dialog{$token} = { 120 $dialog{$token} = 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"; 121 dialog_tell $token, $dialog{$token}, "hi";
95 return; 122 return;
96 } 123 }
97 } 124 }
98 125
99 $pl->send ("ext $token error"); 126 $pl->send ("ext $token error");
102cf::register_extcmd npc_dialog_tell => sub { 129cf::register_extcmd npc_dialog_tell => sub {
103 my ($pl, $data) = @_; 130 my ($pl, $data) = @_;
104 131
105 my ($token, $msg) = split / /, $data, 2; 132 my ($token, $msg) = split / /, $data, 2;
106 133
107 dialog_tell $dialog{$token}, $msg 134 dialog_tell $token, $dialog{$token}, $msg
108 if $dialog{$token}; 135 if $dialog{$token};
109}; 136};
110 137
111cf::register_extcmd npc_dialog_end => sub { 138cf::register_extcmd npc_dialog_end => sub {
112 my ($pl, $token) = @_; 139 my ($pl, $token) = @_;
113 140
114 delete $dialog{$token}; 141 delete $dialog{$token};
115}; 142};
116 143
144sub on_logout {
145 my ($pl, $host) = @_;
146
147 delete $dialog{$_} for grep $pl->ob == $dialog{$_}{ob}, keys %dialog;
148
149 0
150}
151
117sub on_clock { 152sub on_clock {
118 return 0 unless %dialog; 153 return 0 unless %dialog;
119 154
120 while (my ($token, $dialog) = each %dialog) { 155 while (my ($token, $dialog) = each %dialog) {
121 if (my $pl = cf::player::find $dialog->{name}) {
122 my (undef, $dx, $dy) = $pl->ob->rangevector ($dialog->{npc}); 156 my (undef, $dx, $dy) = $dialog->{ob}->rangevector ($dialog->{npc});
123 next if (abs $dx) <= 2 && (abs $dy) <= 2; 157 next if (abs $dx) <= 2 && (abs $dy) <= 2;
124 158
125 $pl->send ("ext $token out_of_range"); 159 $dialog->{ob}->contr->send ("ext $token out_of_range");
126 }
127 delete $dialog{$token}; 160 delete $dialog{$token};
128 } 161 }
129 162
130 0 163 0
131} 164}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines