ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cf.schmorp.de/maps/perl/cfplus.ext
Revision: 1.16
Committed: Fri Dec 15 19:11:46 2006 UTC (17 years, 7 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.15: +0 -0 lines
State: FILE REMOVED
Log Message:
move .ext to server

File Contents

# Content
1 #! perl
2
3 # additional support for cfplus client
4
5 use NPC_Dialogue;
6
7 =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 cf::register_extcmd cfplus_support => sub {
24 my ($pl, $msg) = @_;
25
26 # $msg->{version}
27
28 (version => 2)
29 };
30
31 my %dialog; # currently active dialogs
32
33 my $timer = Event->timer (interval => 0.2, parked => 1, data => cf::WF_AUTOCANCEL, cb => sub {
34 while (my ($id, $dialog) = each %dialog) {
35 my (undef, $dx, $dy) = $dialog->{ob}->rangevector ($dialog->{npc});
36 next if (abs $dx) <= 2 && (abs $dy) <= 2;
37
38 $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "out of range");
39 delete $dialog{$id};
40 }
41
42 $_[0]->w->stop unless keys %dialog;
43 });
44
45 sub dialog_tell {
46 my ($id, $dialog, $msg) = @_;
47
48 my $pl = $dialog->{ob}->contr;
49 my ($reply, @kw) = $dialog->tell ($msg);
50 $reply = "..." unless $reply;
51
52 $pl->ext_reply ($id => msgtype => "reply", msg => $reply, add_topics => \@kw);
53 }
54
55 =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 cf::register_extcmd lookat => sub {
68 my ($pl, $msg) = @_;
69 my ($dx, $dy) = @$msg{qw(dx dy)};
70
71 my $near = (abs $dx) <= 2 && (abs $dy) <= 2;
72
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 if $near && NPC_Dialogue::has_dialogue $ob;
79 }
80 }
81
82 %res
83 };
84
85 =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 cf::register_extcmd npc_dialog_begin => sub {
98 my ($pl, $msg) = @_;
99 my ($id, $dx, $dy) = @$msg{qw(msgid dx dy)};
100
101 return unless (abs $dx) <= 2 && (abs $dy) <= 2;
102 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 if (NPC_Dialogue::has_dialogue $npc) {
106 $dialog{$id} = new NPC_Dialogue ob => $pl->ob, npc => $npc;
107 dialog_tell $id, $dialog{$id}, "hi";
108 $timer->start;
109 return;
110 }
111 }
112
113 (msgtype => "error", msg => "nothing to talk to found")
114 };
115
116 =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 cf::register_extcmd npc_dialog_tell => sub {
129 my ($pl, $msg) = @_;
130
131 dialog_tell $msg->{msgid}, $dialog{$msg->{msgid}}, $msg->{msg}
132 if $dialog{$msg->{msgid}};
133
134 ()
135 };
136
137 =item extcmd npc_dialog_end { msgid => $id }
138
139 Finishes the dialog, invalidating the handle.
140
141 =cut
142
143 cf::register_extcmd npc_dialog_end => sub {
144 my ($pl, $msg) = @_;
145
146 delete $dialog{$msg->{msgid}};
147
148 ()
149 };
150
151 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
159 =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 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 cvs_root => the (http) url where the cvs root for downloading is located
168 lib_root => the (http) url where crossfire.0 and archetypes can be found
169 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 cf::register_extcmd editor_support => sub {
188 my ($pl, $msg) = @_;
189
190 map +($_ => $cf::CFG{"editor_$_"}), qw(servertype gameserver testserver cvs_root lib_root builder_ui)
191 };
192
193 sub unload {
194 while (my ($id, $dialog) = each %dialog) {
195 $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "npc dialogue module was reloaded");
196 }
197
198 %dialog = ();
199 }
200
201 =back
202
203 =cut
204