ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/maps/perl/cfplus.ext
Revision: 1.3
Committed: Mon Jun 19 10:15:10 2006 UTC (17 years, 11 months ago) by root
Branch: MAIN
Changes since 1.2: +81 -48 lines
Log Message:
rewrite npc dialogue to be more generic, to be used in other modules soon

File Contents

# User Rev Content
1 root 1.1 #! perl
2    
3     # additional support for cfplus client
4    
5     cf::register_extcmd cfplus_support => sub {
6     my ($pl, $data) = @_;
7    
8     my ($token, $client_version) = split / /, $data, 2;
9    
10     $pl->send ("ext $token 1");
11     };
12    
13 root 1.3 {
14     package NPC_Dialogue;
15    
16     sub has_dialogue {
17     my ($ob) = @_;
18    
19     $ob->get_message =~ /^\@match /;
20     }
21    
22     sub parse_message($) {
23     map [split /\n/, $_, 2],
24     grep length,
25     split /^\@match /m,
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 root 1.1
41 root 1.3 sub greet {
42     my ($self) = @_;
43 root 1.1
44 root 1.3 $self->tell ("hi")
45     }
46 root 1.1
47 root 1.3 sub tell {
48     my ($self, $msg) = @_;
49 root 1.1
50 root 1.3 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 root 1.1 }
68     }
69 root 1.3
70     return wantarray ? ($reply, @kw) : $reply;
71 root 1.1 }
72     }
73     }
74     }
75    
76 root 1.3 ()
77     }
78    
79     my %dialog; # currently active dialogs
80    
81     sub dialog_tell {
82     my ($token, $dialog, $msg) = @_;
83    
84     my $pl = $dialog->{ob}->contr;
85     my ($reply, @kw) = $dialog->tell ($msg);
86     $reply = "..." unless $reply;
87     $pl->send ("ext $token msg " . join "\x00", $reply, @kw);
88 root 1.1 }
89    
90     # return "interesting" information about the given tile
91     # currently only returns the npc_dialog title when a dialog is possible
92     cf::register_extcmd lookat => sub {
93     my ($pl, $data) = @_;
94    
95     my ($token, $dx, $dy) = split / /, $data;
96 root 1.3 my $near = (abs $dx) <= 2 && (abs $dy) <= 2;
97 root 1.1
98     my %res;
99    
100     if ($pl->cell_visible ($dx, $dy)) {
101     for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
102     $res{npc_dialog} = $ob->name
103 root 1.3 if $near && NPC_Dialogue::has_dialogue $ob;
104 root 1.1 }
105     }
106    
107     $pl->send ("ext $token " . join "\x00", %res);
108     };
109    
110     cf::register_extcmd npc_dialog_begin => sub {
111     my ($pl, $data) = @_;
112    
113     my ($token, $dx, $dy) = split / /, $data;
114    
115 root 1.2 return unless (abs $dx) <= 2 && (abs $dy) <= 2;
116 root 1.1 return unless $pl->cell_visible ($dx, $dy);
117    
118     for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
119 root 1.3 if (NPC_Dialogue::has_dialogue $npc) {
120     $dialog{$token} = new NPC_Dialogue ob => $pl->ob, npc => $npc;
121     dialog_tell $token, $dialog{$token}, "hi";
122 root 1.1 return;
123     }
124     }
125    
126     $pl->send ("ext $token error");
127     };
128    
129     cf::register_extcmd npc_dialog_tell => sub {
130     my ($pl, $data) = @_;
131    
132     my ($token, $msg) = split / /, $data, 2;
133    
134 root 1.3 dialog_tell $token, $dialog{$token}, $msg
135 root 1.1 if $dialog{$token};
136     };
137    
138     cf::register_extcmd npc_dialog_end => sub {
139     my ($pl, $token) = @_;
140    
141     delete $dialog{$token};
142     };
143    
144 root 1.3 sub on_logout {
145     my ($pl, $host) = @_;
146    
147     delete $dialog{$_} for grep $pl->ob == $dialog{$_}{ob}, keys %dialog;
148    
149     0
150     }
151    
152 root 1.2 sub on_clock {
153     return 0 unless %dialog;
154    
155     while (my ($token, $dialog) = each %dialog) {
156 root 1.3 my (undef, $dx, $dy) = $dialog->{ob}->rangevector ($dialog->{npc});
157     next if (abs $dx) <= 2 && (abs $dy) <= 2;
158 root 1.2
159 root 1.3 $dialog->{ob}->contr->send ("ext $token out_of_range");
160 root 1.2 delete $dialog{$token};
161     }
162    
163     0
164     }
165