ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/cfplus.ext
Revision: 1.3
Committed: Thu Dec 21 22:41:34 2006 UTC (17 years, 5 months ago) by root
Branch: MAIN
CVS Tags: rel-2_0
Changes since 1.2: +2 -2 lines
Log Message:
- updated cf.pm to use a more generic and extendable syntax,
  now that it is clear that we will have multiple "attachable" objects.
  maybe bite the bullet in C++ and make attachable virtual?
- completely rework the syntax for attaching and attachments
- update all extensions

File Contents

# User Rev Content
1 root 1.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 root 1.2 return unless $pl->ob && $pl->ob->map;
72    
73 root 1.1 my $near = (abs $dx) <= 2 && (abs $dy) <= 2;
74    
75     my %res;
76    
77     if ($pl->cell_visible ($dx, $dy)) {
78     for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
79     $res{npc_dialog} = $ob->name
80     if $near && NPC_Dialogue::has_dialogue $ob;
81     }
82     }
83    
84     %res
85     };
86    
87     =item ... = extcmd npc_dialog_begin { msgid => $id, dx => $dx, dy => $dy }
88    
89     Tries to start a dialogue with the mapspace specified by $dx and $dy (see
90     C<extcmd lookat>). The $msgid will be used as a handle for all future
91     messages related to this dialog interaction.
92    
93     It either replies with an error reply or starts a dialog by telling
94     the npc "hi" and returning a reply strcuture as with C<extcmd
95     npc_dialog_tell>.
96    
97     =cut
98    
99     cf::register_extcmd npc_dialog_begin => sub {
100     my ($pl, $msg) = @_;
101     my ($id, $dx, $dy) = @$msg{qw(msgid dx dy)};
102    
103 root 1.2 return unless $pl->ob && $pl->ob->map;
104 root 1.1 return unless (abs $dx) <= 2 && (abs $dy) <= 2;
105     return unless $pl->cell_visible ($dx, $dy);
106    
107     for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
108     if (NPC_Dialogue::has_dialogue $npc) {
109     $dialog{$id} = new NPC_Dialogue ob => $pl->ob, npc => $npc;
110     dialog_tell $id, $dialog{$id}, "hi";
111     $timer->start;
112     return;
113     }
114     }
115    
116     (msgtype => "error", msg => "nothing to talk to found")
117     };
118    
119     =item ... = extcmd npc_dialog_tell { msgid => $id, msg => $text }
120    
121     Tells the NPC the given $text message and returns a reply structure which
122     can have the following keys:
123    
124     msgtype => "reply"
125     msg => $reply_text,
126     add_topics => [additional topic strings]
127     del_topics => [invalidated topic strings]
128    
129     =cut
130    
131     cf::register_extcmd npc_dialog_tell => sub {
132     my ($pl, $msg) = @_;
133    
134     dialog_tell $msg->{msgid}, $dialog{$msg->{msgid}}, $msg->{msg}
135     if $dialog{$msg->{msgid}};
136    
137     ()
138     };
139    
140     =item extcmd npc_dialog_end { msgid => $id }
141    
142     Finishes the dialog, invalidating the handle.
143    
144     =cut
145    
146     cf::register_extcmd npc_dialog_end => sub {
147     my ($pl, $msg) = @_;
148    
149     delete $dialog{$msg->{msgid}};
150    
151     ()
152     };
153    
154 root 1.3 cf::player->attach (
155 root 1.1 on_logout => sub {
156     my ($pl) = @_;
157    
158     delete $dialog{$_} for grep $pl->ob == $dialog{$_}{ob}, keys %dialog;
159     },
160 root 1.3 );
161 root 1.1
162     =item ... = extcmd editor_support
163    
164     Returns the value required by clients that have an editor to download and
165     upload maps from/to the server.
166    
167     servertype => (game|test) type of this server
168     gameserver => the hostname:port of the normal game server
169     testserver => the hostname:port of the test server the maps can be tested on
170     cvs_root => the (http) url where the cvs root for downloading is located
171     lib_root => the (http) url where crossfire.0 and archetypes can be found
172     upload => the (http) url where clients can upload maps
173    
174     If those values are not supplied or empty strings, the server does not
175     support downloading, uploading, testing, respectively.
176    
177     The upload script expects the following values in a multipart form upload:
178    
179     client: a descriptive string describing the editor and version used to upload
180     path: absolute server-side map path beginning with /
181     map: the map file itself
182     mapdir: the cvs root url originally used to download the map
183     revision: cvs-revision originally used to download the map
184     comment: a comment supplied by the user that documents the changes
185     cf_login: crossfire server login
186     cf_password: crossfire server password, optionally used for authentication purposes
187    
188     =cut
189    
190     cf::register_extcmd editor_support => sub {
191     my ($pl, $msg) = @_;
192    
193     map +($_ => $cf::CFG{"editor_$_"}), qw(servertype gameserver testserver cvs_root lib_root builder_ui)
194     };
195    
196     sub unload {
197     while (my ($id, $dialog) = each %dialog) {
198     $dialog->{ob}->contr->ext_reply ($id => msgtype => "error", msg => "npc dialogue module was reloaded");
199     }
200    
201     %dialog = ();
202     }
203    
204     =back
205    
206     =cut
207