ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/maps/perl/cfplus.ext
Revision: 1.13
Committed: Sat Oct 14 14:13:40 2006 UTC (17 years, 7 months ago) by root
Branch: MAIN
Changes since 1.12: +5 -6 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #! perl
2    
3     # additional support for cfplus client
4    
5 root 1.4 use NPC_Dialogue;
6    
7 root 1.11 =head1 CF+ protocol extensions
8    
9     This module implements protocol extensions for use by the CF+ client, but
10     can be used by other clients as well. It uses the C<extcmd> mechanism
11     exclusively.
12    
13     =over 4
14    
15     =item ... = extcmd cfplus_support { version => $client_version }
16    
17     Registers the client the the server. the client should send the highest
18     version of the protocol it supports itself, and the server returns the
19     highest version of the protocol it supports in the C<version> key itself.
20    
21     =cut
22    
23 root 1.1 cf::register_extcmd cfplus_support => sub {
24 root 1.8 my ($pl, $msg) = @_;
25 root 1.1
26 root 1.8 # $msg->{version}
27 root 1.1
28 root 1.11 (version => 2)
29 root 1.1 };
30    
31 root 1.3 my %dialog; # currently active dialogs
32    
33 root 1.5 my $timer = Event->timer (interval => 0.2, parked => 1, cb => sub {
34 root 1.8 while (my ($id, $dialog) = each %dialog) {
35 root 1.5 my (undef, $dx, $dy) = $dialog->{ob}->rangevector ($dialog->{npc});
36     next if (abs $dx) <= 2 && (abs $dy) <= 2;
37    
38 root 1.8 $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "out of range");
39     delete $dialog{$id};
40 root 1.5 }
41    
42     $_[0]->w->stop unless keys %dialog;
43     });
44    
45 root 1.3 sub dialog_tell {
46 root 1.8 my ($id, $dialog, $msg) = @_;
47 root 1.3
48     my $pl = $dialog->{ob}->contr;
49     my ($reply, @kw) = $dialog->tell ($msg);
50     $reply = "..." unless $reply;
51 root 1.8
52     $pl->ext_reply ($id => msgtype => "reply", msg => $reply, add_topics => \@kw);
53 root 1.1 }
54    
55 root 1.11 =item ... = extcmd lookat { dx => $dx, dy => $dy }
56    
57     "Looks at" the mapspace displaced (dx|dy) relative to the player
58     and returns "interesting" information about it.
59    
60     Keys it can return include:
61    
62     npc_dialog => $name
63     There is an npc or other object that can "talk" to the player.
64    
65     =cut
66    
67 root 1.1 cf::register_extcmd lookat => sub {
68 root 1.8 my ($pl, $msg) = @_;
69     my ($dx, $dy) = @$msg{qw(dx dy)};
70 root 1.1
71 root 1.3 my $near = (abs $dx) <= 2 && (abs $dy) <= 2;
72 root 1.1
73     my %res;
74    
75     if ($pl->cell_visible ($dx, $dy)) {
76     for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
77     $res{npc_dialog} = $ob->name
78 root 1.3 if $near && NPC_Dialogue::has_dialogue $ob;
79 root 1.1 }
80     }
81    
82 root 1.8 %res
83 root 1.1 };
84    
85 root 1.11 =item ... = extcmd npc_dialog_begin { msgid => $id, dx => $dx, dy => $dy }
86    
87     Tries to start a dialogue with the mapspace specified by $dx and $dy (see
88     C<extcmd lookat>). The $msgid will be used as a handle for all future
89     messages related to this dialog interaction.
90    
91     It either replies with an error reply or starts a dialog by telling
92     the npc "hi" and returning a reply strcuture as with C<extcmd
93     npc_dialog_tell>.
94    
95     =cut
96    
97 root 1.1 cf::register_extcmd npc_dialog_begin => sub {
98 root 1.8 my ($pl, $msg) = @_;
99     my ($id, $dx, $dy) = @$msg{qw(msgid dx dy)};
100 root 1.1
101 root 1.2 return unless (abs $dx) <= 2 && (abs $dy) <= 2;
102 root 1.1 return unless $pl->cell_visible ($dx, $dy);
103    
104     for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
105 root 1.3 if (NPC_Dialogue::has_dialogue $npc) {
106 root 1.8 $dialog{$id} = new NPC_Dialogue ob => $pl->ob, npc => $npc;
107     dialog_tell $id, $dialog{$id}, "hi";
108 root 1.5 $timer->start;
109 root 1.1 return;
110     }
111     }
112    
113 root 1.8 (msgtype => "error", msg => "nothing to talk to found")
114 root 1.1 };
115    
116 root 1.11 =item ... = extcmd npc_dialog_tell { msgid => $id, msg => $text }
117    
118     Tells the NPC the given $text message and returns a reply structure which
119     can have the following keys:
120    
121     msgtype => "reply"
122     msg => $reply_text,
123     add_topics => [additional topic strings]
124     del_topics => [invalidated topic strings]
125    
126     =cut
127    
128 root 1.1 cf::register_extcmd npc_dialog_tell => sub {
129 root 1.8 my ($pl, $msg) = @_;
130 root 1.1
131 root 1.8 dialog_tell $msg->{msgid}, $dialog{$msg->{msgid}}, $msg->{msg}
132     if $dialog{$msg->{msgid}};
133 root 1.1
134 root 1.8 ()
135 root 1.1 };
136    
137 root 1.11 =item extcmd npc_dialog_end { msgid => $id }
138    
139     Finishes the dialog, invalidating the handle.
140    
141     =cut
142    
143 root 1.1 cf::register_extcmd npc_dialog_end => sub {
144 root 1.8 my ($pl, $msg) = @_;
145    
146     delete $dialog{$msg->{msgid}};
147 root 1.1
148 root 1.8 ()
149 root 1.1 };
150    
151 root 1.9 cf::attach_to_players
152     on_logout => sub {
153     my ($pl) = @_;
154    
155     delete $dialog{$_} for grep $pl->ob == $dialog{$_}{ob}, keys %dialog;
156     },
157     ;
158 root 1.3
159 root 1.12 =item ... = extcmd editor_support
160    
161     Returns the value required by clients that have an editor to download and
162     upload maps from/to the server.
163    
164 root 1.13 servertype => (game|test) type of this server
165     gameserver => the hostname:port of the normal game server
166     testserver => the hostname:port of the test server the maps can be tested on
167 root 1.12 cvs_root => the (http) url where the cvs root for downloading is located
168 root 1.13 lib_root => the (http) url where crossfire.0 and archetypes can be found
169 root 1.12 upload => the (http) url where clients can upload maps
170    
171     If those values are not supplied or empty strings, the server does not
172     support downloading, uploading, testing, respectively.
173    
174     The upload script expects the following values in a multipart form upload:
175    
176     client: a descriptive string describing the editor and version used to upload
177     path: absolute server-side map path beginning with /
178     map: the map file itself
179     mapdir: the cvs root url originally used to download the map
180     revision: cvs-revision originally used to download the map
181     comment: a comment supplied by the user that documents the changes
182     cf_login: crossfire server login
183     cf_password: crossfire server password, optionally used for authentication purposes
184    
185     =cut
186    
187 root 1.11 cf::register_extcmd editor_support => sub {
188     my ($pl, $msg) = @_;
189    
190 root 1.13 map +($_ => $cf::CFG{"editor_$_"}), qw(servertype gameserver testserver cvs_root lib_root)
191 root 1.11 };
192    
193 root 1.10 sub unload {
194 root 1.8 while (my ($id, $dialog) = each %dialog) {
195     $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "npc dialogue module was reloaded");
196 root 1.6 }
197    
198     %dialog = ();
199     }
200    
201 root 1.11 =back
202    
203     =cut
204 root 1.2