… | |
… | |
62 | my %res; |
62 | my %res; |
63 | |
63 | |
64 | if ($pl->cell_visible ($dx, $dy)) { |
64 | if ($pl->cell_visible ($dx, $dy)) { |
65 | 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)) { |
66 | $res{npc_dialog} = [$ob->name, $dx, $dy] |
66 | $res{npc_dialog} = [$ob->name, $dx, $dy] |
67 | if $near && NPC_Dialogue::has_dialogue $ob && !$pl->{npc_dialog}; |
67 | if $near && $ob->has_dialogue && !$pl->{npc_dialog}; |
68 | } |
68 | } |
69 | } |
69 | } |
70 | |
70 | |
71 | %res |
71 | %res |
72 | }; |
72 | }; |
… | |
… | |
85 | |
85 | |
86 | cf::register_extcmd npc_dialog_begin => sub { |
86 | cf::register_extcmd npc_dialog_begin => sub { |
87 | my ($pl, $id, $token) = @_; |
87 | my ($pl, $id, $token) = @_; |
88 | |
88 | |
89 | #TODO: |
89 | #TODO: |
90 | # this is not a request, so returnign does no good: make it a request and die on error |
90 | # this is not a request, so returning does no good: make it a request and die on error |
91 | |
91 | |
92 | return unless $pl->ob && $pl->ob->map; |
92 | return unless $pl->ob && $pl->ob->map; |
93 | |
93 | |
94 | my ($name, $dx, $dy) = @$token; |
94 | my ($name, $dx, $dy) = @$token; |
95 | |
95 | |
96 | return (error => "too far away") unless (abs $dx) <= 2 && (abs $dy) <= 2; |
96 | return (error => "too far away") unless (abs $dx) <= 2 && (abs $dy) <= 2; |
97 | return (error => "nothing to talk there") unless $pl->cell_visible ($dx, $dy); |
97 | return (error => "nothing to talk there") unless $pl->cell_visible ($dx, $dy); |
98 | return (error => "only one dialog can be open at a time") 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 |
99 | |
99 | |
100 | 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)) { |
101 | if (NPC_Dialogue::has_dialogue $npc) { |
101 | if ($npc->has_dialogue) { |
102 | $pl->attach ("npc_dialog_active"); |
102 | $pl->attach ("npc_dialog_active"); |
103 | $pl->{npc_dialog} = new NPC_Dialogue pl => $pl, npc => $npc, id => $id; |
103 | $pl->{npc_dialog} = new NPC_Dialogue pl => $pl, npc => $npc, id => $id; |
104 | dialog_tell $id, $pl->{npc_dialog}, "hi"; |
104 | dialog_tell $id, $pl->{npc_dialog}, "hi"; |
105 | return; |
105 | return; |
106 | } |
106 | } |
… | |
… | |
149 | |
149 | |
150 | servertype => (game|test) type of this server |
150 | servertype => (game|test) type of this server |
151 | gameserver => the hostname:port of the normal game server |
151 | gameserver => the hostname:port of the normal game server |
152 | 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 |
153 | 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 |
154 | 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 |
155 | upload => the (http) url where clients can upload maps |
155 | upload => the (http) url where clients can upload maps |
156 | |
156 | |
157 | If those values are not supplied or empty strings, the server does not |
157 | If those values are not supplied or empty strings, the server does not |
158 | support downloading, uploading, testing, respectively. |
158 | support downloading, uploading, testing, respectively. |
159 | |
159 | |
… | |
… | |
163 | path: absolute server-side map path beginning with / |
163 | path: absolute server-side map path beginning with / |
164 | map: the map file itself |
164 | map: the map file itself |
165 | mapdir: the cvs root url originally used to download the map |
165 | mapdir: the cvs root url originally used to download the map |
166 | revision: cvs-revision originally used to download the map |
166 | revision: cvs-revision originally used to download the map |
167 | comment: a comment supplied by the user that documents the changes |
167 | comment: a comment supplied by the user that documents the changes |
168 | cf_login: crossfire server login |
168 | login: deliantra server login |
169 | cf_password: crossfire server password, optionally used for authentication purposes |
169 | password: deliantra server password, optionally used for authentication purposes |
170 | |
170 | |
171 | =cut |
171 | =cut |
172 | |
172 | |
173 | cf::register_extcmd editor_support => sub { |
173 | cf::register_extcmd editor_support => sub { |
174 | my ($pl, %msg) = @_; |
174 | my ($pl, %msg) = @_; |
175 | |
175 | |
176 | map +($_ => $cf::CFG{"editor_$_"}), qw(servertype gameserver testserver cvs_root lib_root builder_ui) |
176 | my %cfg = map +($_ => $cf::CFG{"editor_$_"}), qw(servertype servertypes gameserver testserver cvs_root lib_root builder_ui); |
|
|
177 | |
|
|
178 | # clients 2.10 and below check for type and "nameserver" :/ |
|
|
179 | $cfg{type} = $cfg{servertype}; |
|
|
180 | $cfg{nameserver} = $cfg{gameserver}; |
|
|
181 | |
|
|
182 | %cfg |
177 | }; |
183 | }; |
178 | |
184 | |
179 | sub unload { |
185 | sub unload { |
180 | for my $pl (cf::player::list) { |
186 | for my $pl (cf::player::list) { |
181 | if (my $dialog = delete $pl->{npc_dialog}) { |
187 | if (my $dialog = delete $pl->{npc_dialog}) { |
… | |
… | |
190 | my ($pl) = @_; |
196 | my ($pl) = @_; |
191 | |
197 | |
192 | delete $pl->{npc_dialog}; |
198 | delete $pl->{npc_dialog}; |
193 | $pl->detach ("npc_dialog_active"); |
199 | $pl->detach ("npc_dialog_active"); |
194 | }, |
200 | }, |
|
|
201 | on_map_change => sub { |
|
|
202 | my ($pl) = @_; |
|
|
203 | |
|
|
204 | my $dialog = delete $pl->{npc_dialog} |
|
|
205 | or return; |
|
|
206 | |
|
|
207 | $pl->ext_msg ($dialog->{id} => error => "out of range"); |
|
|
208 | $pl->detach ("npc_dialog_active"); |
|
|
209 | }, |
195 | on_move => sub { |
210 | on_move => sub { |
196 | my ($pl, $dir) = @_; |
211 | my ($pl, $dir) = @_; |
197 | |
212 | |
198 | # must delay a bit :/ |
213 | # must delay a bit :/ |
199 | Event->timer (after => 0, cb => sub { |
214 | my $delay; $delay = AE::timer 0, 0, sub { |
200 | $_[0]->w->cancel; |
215 | undef $delay; |
201 | |
216 | |
202 | if (my $dialog = $pl->{npc_dialog}) { |
217 | if (my $dialog = $pl->{npc_dialog}) { |
203 | my (undef, $dx, $dy) = $pl->ob->rangevector ($dialog->{npc}); |
218 | my (undef, $dx, $dy) = $pl->ob->rangevector ($dialog->{npc}); |
204 | |
219 | |
205 | return if (abs $dx) <= 2 && (abs $dy) <= 2; |
220 | return if (abs $dx) <= 2 && (abs $dy) <= 2; |
206 | |
221 | |
|
|
222 | delete $pl->{npc_dialog}; |
207 | $pl->ext_msg ($dialog->{id} => error => "out of range"); |
223 | $pl->ext_msg ($dialog->{id} => error => "out of range"); |
|
|
224 | $pl->detach ("npc_dialog_active"); |
208 | } |
225 | } |
209 | |
|
|
210 | delete $pl->{npc_dialog}; |
|
|
211 | $pl->detach ("npc_dialog_active"); |
|
|
212 | }); |
226 | }; |
213 | }, |
227 | }, |
214 | ; |
228 | ; |
215 | |
229 | |
216 | cf::player->attach ( |
230 | cf::player->attach ( |
217 | on_login => sub { |
231 | on_login => sub { |