ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/cfplus.ext
(Generate patch)

Comparing deliantra/server/ext/cfplus.ext (file contents):
Revision 1.5 by root, Sat Jun 16 14:35:41 2007 UTC vs.
Revision 1.14 by root, Sat Dec 13 20:34:37 2008 UTC

19highest version of the protocol it supports in the C<version> key itself. 19highest version of the protocol it supports in the C<version> key itself.
20 20
21=cut 21=cut
22 22
23cf::register_extcmd cfplus_support => sub { 23cf::register_extcmd cfplus_support => sub {
24 my ($pl, $msg) = @_; 24 my ($pl, %msg) = @_;
25 25
26 # $msg->{version} 26 $pl->ns->{cfplus_ext} = $msg{version};
27 27
28 ( 28 (version => $msg{version} >= 2 ? 2 : 0)
29 version => 2,
30 )
31}; 29};
32 30
33sub dialog_tell { 31sub dialog_tell {
34 my ($id, $dialog, $msg) = @_; 32 my ($id, $dialog, $msg) = @_;
35 33
36 my $pl = $dialog->{pl}; 34 my $pl = $dialog->{pl};
37 my ($reply, @kw) = $dialog->tell ($msg); 35 my ($reply, @kw) = $dialog->tell ($msg);
36
38 $reply = "..." unless $reply; 37 $reply = "..." unless defined $reply;
39 38
40 $pl->ext_reply ($id => msgtype => "reply", msg => $reply, add_topics => \@kw); 39 $pl->ext_msg ($id, update => msg => $pl->expand_cfpod ($reply), add_topics => \@kw)
40 if $reply ne ""; # NPC might not want to say, or wants to say something later
41} 41}
42 42
43=item ... = extcmd lookat { dx => $dx, dy => $dy } 43=item ... = extcmd lookat { dx => $dx, dy => $dy }
44 44
45"Looks at" the mapspace displaced (dx|dy) relative to the player 45"Looks at" the mapspace displaced (dx|dy) relative to the player
51 There is an npc or other object that can "talk" to the player. 51 There is an npc or other object that can "talk" to the player.
52 52
53=cut 53=cut
54 54
55cf::register_extcmd lookat => sub { 55cf::register_extcmd lookat => sub {
56 my ($pl, $msg) = @_; 56 my ($pl, $dx, $dy) = @_;
57 my ($dx, $dy) = @$msg{qw(dx dy)};
58 57
59 return unless $pl->ob && $pl->ob->map; 58 return unless $pl->ob && $pl->ob->map;
60 59
61 my $near = (abs $dx) <= 2 && (abs $dy) <= 2; 60 my $near = (abs $dx) <= 2 && (abs $dy) <= 2;
62 61
63 my %res; 62 my %res;
64 63
65 if ($pl->cell_visible ($dx, $dy)) { 64 if ($pl->cell_visible ($dx, $dy)) {
66 for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) { 65 for my $ob ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
67 $res{npc_dialog} = $ob->name 66 $res{npc_dialog} = [$ob->name, $dx, $dy]
68 if $near && NPC_Dialogue::has_dialogue $ob && !$pl->{npc_dialog}; 67 if $near && $ob->has_dialogue && !$pl->{npc_dialog};
69 } 68 }
70 } 69 }
71 70
72 %res 71 %res
73}; 72};
83npc_dialog_tell>. 82npc_dialog_tell>.
84 83
85=cut 84=cut
86 85
87cf::register_extcmd npc_dialog_begin => sub { 86cf::register_extcmd npc_dialog_begin => sub {
88 my ($pl, $msg) = @_; 87 my ($pl, $id, $token) = @_;
89 my ($id, $dx, $dy) = @$msg{qw(msgid dx dy)}; 88
89 #TODO:
90 # this is not a request, so returning does no good: make it a request and die on error
90 91
91 return unless $pl->ob && $pl->ob->map; 92 return unless $pl->ob && $pl->ob->map;
93
94 my ($name, $dx, $dy) = @$token;
95
92 return unless (abs $dx) <= 2 && (abs $dy) <= 2; 96 return (error => "too far away") unless (abs $dx) <= 2 && (abs $dy) <= 2;
93 return unless $pl->cell_visible ($dx, $dy); 97 return (error => "nothing to talk there") unless $pl->cell_visible ($dx, $dy);
94 return if $pl->{npc_dialog}; # only one dialog at a time 98 return (error => "only one dialog can be open at a time") if $pl->{npc_dialog}; # only one dialog at a time
95 99
96 for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) { 100 for my $npc ($pl->ob->map->at ($pl->ob->x + $dx, $pl->ob->y + $dy)) {
97 if (NPC_Dialogue::has_dialogue $npc) { 101 if ($npc->has_dialogue) {
98 $pl->attach ("npc_dialog_active"); 102 $pl->attach ("npc_dialog_active");
99 $pl->{npc_dialog} = new NPC_Dialogue pl => $pl, npc => $npc; 103 $pl->{npc_dialog} = new NPC_Dialogue pl => $pl, npc => $npc, id => $id;
100 dialog_tell $id, $pl->{npc_dialog}, "hi"; 104 dialog_tell $id, $pl->{npc_dialog}, "hi";
101 return; 105 return;
102 } 106 }
103 } 107 }
104 108
105 (msgtype => "error", msg => "nothing to talk to found") 109 (error => "nothing to talk to to found")
106}; 110};
107 111
108=item ... = extcmd npc_dialog_tell { msgid => $id, msg => $text } 112=item ... = extcmd npc_dialog_tell { msgid => $id, msg => $text }
109 113
110Tells the NPC the given $text message and returns a reply structure which 114Tells the NPC the given $text message and returns a reply structure which
111can have the following keys: 115can have the following keys:
112 116
113 msgtype => "reply"
114 msg => $reply_text, 117 msg => $reply_text,
115 add_topics => [additional topic strings] 118 add_topics => [additional topic strings]
116 del_topics => [invalidated topic strings] 119 del_topics => [invalidated topic strings]
117 120
118=cut 121=cut
119 122
120cf::register_extcmd npc_dialog_tell => sub { 123cf::register_extcmd npc_dialog_tell => sub {
121 my ($pl, $msg) = @_; 124 my ($pl, $id, $msg) = @_;
122 125
123 if (my $dialog = $pl->{npc_dialog}) { 126 if (my $dialog = $pl->{npc_dialog}) {
124 dialog_tell $msg->{msgid}, $dialog, $msg->{msg}; 127 dialog_tell $id, $dialog, $msg;
125 } 128 }
126
127 ()
128}; 129};
129 130
130=item extcmd npc_dialog_end { msgid => $id } 131=item extcmd npc_dialog_end { msgid => $id }
131 132
132Finishes the dialog, invalidating the handle. 133Finishes the dialog, invalidating the handle.
133 134
134=cut 135=cut
135 136
136cf::register_extcmd npc_dialog_end => sub { 137cf::register_extcmd npc_dialog_end => sub {
137 my ($pl, $msg) = @_; 138 my ($pl, $id) = @_;
138 139
139 if (my $dialog = delete $pl->{npc_dialog}) { 140 if (my $dialog = delete $pl->{npc_dialog}) {
140 $pl->detach ("ncpa_dialog_active"); 141 $pl->detach ("ncp_dialog_active");
141 } 142 }
142
143 ()
144}; 143};
145 144
146=item ... = extcmd editor_support 145=item ... = extcmd editor_support
147 146
148Returns the value required by clients that have an editor to download and 147Returns the value required by clients that have an editor to download and
150 149
151 servertype => (game|test) type of this server 150 servertype => (game|test) type of this server
152 gameserver => the hostname:port of the normal game server 151 gameserver => the hostname:port of the normal game server
153 testserver => the hostname:port of the test server the maps can be tested on 152 testserver => the hostname:port of the test server the maps can be tested on
154 cvs_root => the (http) url where the cvs root for downloading is located 153 cvs_root => the (http) url where the cvs root for downloading is located
155 lib_root => the (http) url where crossfire.0 and archetypes can be found 154 lib_root => the (http) url where archetypes data can be found
156 upload => the (http) url where clients can upload maps 155 upload => the (http) url where clients can upload maps
157 156
158If those values are not supplied or empty strings, the server does not 157If those values are not supplied or empty strings, the server does not
159support downloading, uploading, testing, respectively. 158support downloading, uploading, testing, respectively.
160 159
164 path: absolute server-side map path beginning with / 163 path: absolute server-side map path beginning with /
165 map: the map file itself 164 map: the map file itself
166 mapdir: the cvs root url originally used to download the map 165 mapdir: the cvs root url originally used to download the map
167 revision: cvs-revision originally used to download the map 166 revision: cvs-revision originally used to download the map
168 comment: a comment supplied by the user that documents the changes 167 comment: a comment supplied by the user that documents the changes
169 cf_login: crossfire server login 168 login: deliantra server login
170 cf_password: crossfire server password, optionally used for authentication purposes 169 password: deliantra server password, optionally used for authentication purposes
171 170
172=cut 171=cut
173 172
174cf::register_extcmd editor_support => sub { 173cf::register_extcmd editor_support => sub {
175 my ($pl, $msg) = @_; 174 my ($pl, %msg) = @_;
176 175
177 map +($_ => $cf::CFG{"editor_$_"}), qw(servertype gameserver testserver cvs_root lib_root builder_ui) 176 map +($_ => $cf::CFG{"editor_$_"}), qw(servertype gameserver testserver cvs_root lib_root builder_ui)
178}; 177};
179 178
180sub unload { 179sub unload {
181 for my $pl (cf::player::list) { 180 for my $pl (cf::player::list) {
182 if (my $dialog = delete $pl->{npc_dialog}) { 181 if (my $dialog = delete $pl->{npc_dialog}) {
183 $pl->detach ("npc_dialog_active"); 182 $pl->detach ("npc_dialog_active");
184 $pl->ext_reply ($dialog->{id} => msgtype => "error", msg => "npc dialogue module was reloaded"); 183 $pl->ext_msg ($dialog->{id} => error => "npc dialogue module was reloaded");
185 } 184 }
186 } 185 }
187} 186}
188 187
189cf::player::attachment npc_dialog_active => 188cf::player::attachment npc_dialog_active =>
194 $pl->detach ("npc_dialog_active"); 193 $pl->detach ("npc_dialog_active");
195 }, 194 },
196 on_move => sub { 195 on_move => sub {
197 my ($pl, $dir) = @_; 196 my ($pl, $dir) = @_;
198 197
198 # must delay a bit :/
199 my $delay; $delay = EV::timer 0, 0, sub {
200 undef $delay;
201
199 if (my $dialog = $pl->{npc_dialog}) { 202 if (my $dialog = $pl->{npc_dialog}) {
200 warn "on_move<@_>\n";#d#
201 warn $pl->ob;
202 warn $dialog;
203 warn $dialog->{npc};
204 warn $dialog->{npc}->is_valid;
205
206 my (undef, $dx, $dy) = $pl->ob->rangevector ($dialog->{npc}); 203 my (undef, $dx, $dy) = $pl->ob->rangevector ($dialog->{npc});
207 204
208 return if (abs $dx) <= 2 && (abs $dy) <= 2; 205 return if (abs $dx) <= 2 && (abs $dy) <= 2;
209 206
210 $pl->ext_reply ($dialog->{id} => msgtype => "error", msg => "out of range"); 207 $pl->ext_msg ($dialog->{id} => error => "out of range");
211 } 208 }
212 209
213 delete $pl->{npc_dialog}; 210 delete $pl->{npc_dialog};
214 $pl->detach ("npc_dialog_active"); 211 $pl->detach ("npc_dialog_active");
212 };
215 }, 213 },
216; 214;
217 215
218cf::player->attach ( 216cf::player->attach (
219 on_login => sub { 217 on_login => sub {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines