1 | |
1 | |
2 | /* |
2 | /* |
3 | * static char *rcsid_item_c = |
3 | * static char *rcsid_item_c = |
4 | * "$Id: item.c,v 1.1.1.1 2006/02/03 07:14:44 root Exp $"; |
4 | * "$Id: item.c,v 1.4 2006/06/11 20:45:05 root Exp $"; |
5 | */ |
5 | */ |
6 | |
6 | |
7 | /* |
7 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
8 | CrossFire, A Multiplayer game for X-windows |
9 | |
9 | |
… | |
… | |
131 | flags |= F_LOCKED; |
131 | flags |= F_LOCKED; |
132 | |
132 | |
133 | return flags; |
133 | return flags; |
134 | } |
134 | } |
135 | |
135 | |
|
|
136 | /* Used in the send_look to put object head into SockList |
|
|
137 | * sl for socket ns. Need socket to know if we need to send |
|
|
138 | * animation of face to the client. |
|
|
139 | */ |
|
|
140 | static void add_object_to_socklist(NewSocket *ns, SockList *sl, object *head) |
|
|
141 | { |
|
|
142 | int flags, len, anim_speed; |
|
|
143 | char item_n[MAX_BUF]; |
|
|
144 | const char *item_p; |
|
|
145 | |
|
|
146 | flags = query_flags (head); |
|
|
147 | if (QUERY_FLAG(head, FLAG_NO_PICK)) |
|
|
148 | flags |= F_NOPICK; |
|
|
149 | |
|
|
150 | if (!(ns->faces_sent[head->face->number] & NS_FACESENT_FACE)) |
|
|
151 | esrv_send_face(ns, head->face->number,0); |
|
|
152 | |
|
|
153 | if (QUERY_FLAG(head,FLAG_ANIMATE) && !ns->anims_sent[head->animation_id]) |
|
|
154 | esrv_send_animation(ns, head->animation_id); |
|
|
155 | |
|
|
156 | SockList_AddInt(sl, head->count); |
|
|
157 | SockList_AddInt(sl, flags); |
|
|
158 | SockList_AddInt(sl, QUERY_FLAG(head, FLAG_NO_PICK) ? -1 : WEIGHT(head)); |
|
|
159 | SockList_AddInt(sl, head->face->number); |
|
|
160 | |
|
|
161 | if (!head->custom_name) { |
|
|
162 | strncpy(item_n,query_base_name(head, 0),127); |
|
|
163 | item_n[127]=0; |
|
|
164 | len=strlen(item_n); |
|
|
165 | item_p=query_base_name(head, 1); |
|
|
166 | } else { |
|
|
167 | strncpy(item_n,head->custom_name,127); |
|
|
168 | item_n[127]=0; |
|
|
169 | len=strlen(item_n); |
|
|
170 | item_p=head->custom_name; |
|
|
171 | } |
|
|
172 | strncpy(item_n+len+1, item_p, 127); |
|
|
173 | item_n[254]=0; |
|
|
174 | len += strlen(item_n+1+len) + 1; |
|
|
175 | SockList_AddChar(sl, (char ) len); |
|
|
176 | memcpy(sl->buf+sl->len, item_n, len); |
|
|
177 | sl->len += len; |
|
|
178 | |
|
|
179 | SockList_AddShort(sl,head->animation_id); |
|
|
180 | anim_speed=0; |
|
|
181 | if (QUERY_FLAG(head,FLAG_ANIMATE)) { |
|
|
182 | if (head->anim_speed) anim_speed=head->anim_speed; |
|
|
183 | else { |
|
|
184 | if (FABS(head->speed)<0.001) anim_speed=255; |
|
|
185 | else if (FABS(head->speed)>=1.0) anim_speed=1; |
|
|
186 | else anim_speed = (int) (1.0/FABS(head->speed)); |
|
|
187 | } |
|
|
188 | if (anim_speed>255) anim_speed=255; |
|
|
189 | } |
|
|
190 | SockList_AddChar(sl, (char) anim_speed); |
|
|
191 | SockList_AddInt(sl, head->nrof); |
|
|
192 | |
|
|
193 | if (ns->itemcmd == 2) |
|
|
194 | SockList_AddShort(sl, head->client_type); |
|
|
195 | |
|
|
196 | SET_FLAG(head, FLAG_CLIENT_SENT); |
|
|
197 | } |
|
|
198 | |
|
|
199 | |
136 | /** |
200 | /** |
137 | * Send the look window. Don't need to do animations here |
201 | * Send the look window. Don't need to do animations here |
138 | * This sends all the faces to the client, not just updates. This is |
202 | * This sends all the faces to the client, not just updates. This is |
139 | * because object ordering would otherwise be inconsistent |
203 | * because object ordering would otherwise be inconsistent |
140 | */ |
204 | */ |
141 | |
205 | |
142 | void esrv_draw_look(object *pl) |
206 | void esrv_draw_look(object *pl) |
143 | { |
207 | { |
144 | object *tmp, *last; |
208 | object *tmp, *last; |
145 | int flags, got_one=0,anim_speed, start_look=0, end_look=0, len; |
209 | int got_one=0,start_look=0, end_look=0; |
146 | SockList sl; |
210 | SockList sl; |
147 | char buf[MAX_BUF], item_n[MAX_BUF]; |
211 | char buf[MAX_BUF]; |
148 | const char *item_p; |
|
|
149 | |
212 | |
150 | if (!pl->contr->socket.update_look) { |
213 | if (!pl->contr->socket.update_look) { |
151 | LOG(llevDebug,"esrv_draw_look called when update_look was not set\n"); |
214 | LOG(llevDebug,"esrv_draw_look called when update_look was not set\n"); |
152 | return; |
215 | return; |
153 | } else { |
216 | } else { |
… | |
… | |
156 | |
219 | |
157 | if(QUERY_FLAG(pl, FLAG_REMOVED) || pl->map == NULL || |
220 | if(QUERY_FLAG(pl, FLAG_REMOVED) || pl->map == NULL || |
158 | pl->map->in_memory != MAP_IN_MEMORY || out_of_map(pl->map,pl->x,pl->y)) |
221 | pl->map->in_memory != MAP_IN_MEMORY || out_of_map(pl->map,pl->x,pl->y)) |
159 | return; |
222 | return; |
160 | |
223 | |
|
|
224 | if (pl->contr->transport) |
|
|
225 | for (tmp=pl->contr->transport->inv; tmp && tmp->above;tmp=tmp->above) ; |
|
|
226 | else |
161 | for (tmp=get_map_ob(pl->map,pl->x,pl->y); tmp && tmp->above;tmp=tmp->above) |
227 | for (tmp=get_map_ob(pl->map,pl->x,pl->y); tmp && tmp->above;tmp=tmp->above) ; |
162 | ; |
|
|
163 | |
228 | |
164 | sl.buf=malloc(MAXSOCKBUF); |
229 | sl.buf=malloc(MAXSOCKBUF); |
165 | |
230 | |
166 | Write_String_To_Socket(&pl->contr->socket, "delinv 0", strlen("delinv 0")); |
231 | Write_String_To_Socket(&pl->contr->socket, "delinv 0", strlen("delinv 0")); |
167 | sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); |
232 | sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); |
… | |
… | |
182 | SockList_AddShort(&sl,0); |
247 | SockList_AddShort(&sl,0); |
183 | SockList_AddChar(&sl, 0); |
248 | SockList_AddChar(&sl, 0); |
184 | SockList_AddInt(&sl, 0); |
249 | SockList_AddInt(&sl, 0); |
185 | if (pl->contr->socket.itemcmd == 2) |
250 | if (pl->contr->socket.itemcmd == 2) |
186 | SockList_AddShort(&sl, 0); |
251 | SockList_AddShort(&sl, 0); |
|
|
252 | } |
|
|
253 | |
|
|
254 | if (pl->contr->transport) { |
|
|
255 | add_object_to_socklist(&pl->contr->socket, &sl, pl->contr->transport); |
|
|
256 | got_one++; |
187 | } |
257 | } |
188 | |
258 | |
189 | for (last=NULL; tmp!=last; tmp=tmp->below) { |
259 | for (last=NULL; tmp!=last; tmp=tmp->below) { |
190 | object *head; |
260 | object *head; |
191 | |
261 | |
… | |
… | |
215 | break; |
285 | break; |
216 | } |
286 | } |
217 | if (tmp->head) head = tmp->head; |
287 | if (tmp->head) head = tmp->head; |
218 | else head = tmp; |
288 | else head = tmp; |
219 | |
289 | |
220 | flags = query_flags (head); |
290 | add_object_to_socklist(&pl->contr->socket, &sl, head); |
221 | if (QUERY_FLAG(head, FLAG_NO_PICK)) |
|
|
222 | flags |= F_NOPICK; |
|
|
223 | if (!(pl->contr->socket.faces_sent[head->face->number] & NS_FACESENT_FACE)) |
|
|
224 | esrv_send_face(&pl->contr->socket, head->face->number,0); |
|
|
225 | |
|
|
226 | if (QUERY_FLAG(head,FLAG_ANIMATE) && |
|
|
227 | !pl->contr->socket.anims_sent[head->animation_id]) |
|
|
228 | esrv_send_animation(&pl->contr->socket, head->animation_id); |
|
|
229 | |
|
|
230 | SockList_AddInt(&sl, head->count); |
|
|
231 | SockList_AddInt(&sl, flags); |
|
|
232 | SockList_AddInt(&sl, QUERY_FLAG(head, FLAG_NO_PICK) ? -1 : WEIGHT(head)); |
|
|
233 | SockList_AddInt(&sl, head->face->number); |
|
|
234 | |
|
|
235 | if (!head->custom_name) { |
|
|
236 | strncpy(item_n,query_base_name(head, 0),127); |
|
|
237 | item_n[127]=0; |
|
|
238 | len=strlen(item_n); |
|
|
239 | item_p=query_base_name(head, 1); |
|
|
240 | } else { |
|
|
241 | strncpy(item_n,head->custom_name,127); |
|
|
242 | item_n[127]=0; |
|
|
243 | len=strlen(item_n); |
|
|
244 | item_p=head->custom_name; |
|
|
245 | } |
|
|
246 | strncpy(item_n+len+1, item_p, 127); |
|
|
247 | item_n[254]=0; |
|
|
248 | len += strlen(item_n+1+len) + 1; |
|
|
249 | SockList_AddChar(&sl, (char ) len); |
|
|
250 | memcpy(sl.buf+sl.len, item_n, len); |
|
|
251 | sl.len += len; |
|
|
252 | |
|
|
253 | SockList_AddShort(&sl,head->animation_id); |
|
|
254 | anim_speed=0; |
|
|
255 | if (QUERY_FLAG(head,FLAG_ANIMATE)) { |
|
|
256 | if (head->anim_speed) anim_speed=head->anim_speed; |
|
|
257 | else { |
|
|
258 | if (FABS(head->speed)<0.001) anim_speed=255; |
|
|
259 | else if (FABS(head->speed)>=1.0) anim_speed=1; |
|
|
260 | else anim_speed = (int) (1.0/FABS(head->speed)); |
|
|
261 | } |
|
|
262 | if (anim_speed>255) anim_speed=255; |
|
|
263 | } |
|
|
264 | SockList_AddChar(&sl, (char) anim_speed); |
|
|
265 | SockList_AddInt(&sl, head->nrof); |
|
|
266 | |
|
|
267 | if (pl->contr->socket.itemcmd == 2) |
|
|
268 | SockList_AddShort(&sl, head->client_type); |
|
|
269 | |
|
|
270 | SET_FLAG(head, FLAG_CLIENT_SENT); |
|
|
271 | got_one++; |
291 | got_one++; |
272 | |
292 | |
273 | if (sl.len > (MAXSOCKBUF-MAXITEMLEN)) { |
293 | if (sl.len >= (MAXSOCKBUF-MAXITEMLEN)) { |
274 | Send_With_Handling(&pl->contr->socket, &sl); |
294 | Send_With_Handling(&pl->contr->socket, &sl); |
275 | sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); |
295 | sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); |
276 | sl.len=strlen((char*)sl.buf); |
296 | sl.len=strlen((char*)sl.buf); |
277 | SockList_AddInt(&sl, 0); |
297 | SockList_AddInt(&sl, 0); |
278 | got_one=0; |
298 | got_one=0; |
… | |
… | |
289 | * Sends whole inventory. |
309 | * Sends whole inventory. |
290 | */ |
310 | */ |
291 | void esrv_send_inventory(object *pl, object *op) |
311 | void esrv_send_inventory(object *pl, object *op) |
292 | { |
312 | { |
293 | object *tmp; |
313 | object *tmp; |
294 | int flags, got_one=0, anim_speed, len; |
314 | int got_one=0; |
295 | SockList sl; |
315 | SockList sl; |
296 | char item_n[MAX_BUF]; |
|
|
297 | const char *item_p; |
|
|
298 | |
316 | |
299 | sl.buf=malloc(MAXSOCKBUF); |
317 | sl.buf=malloc(MAXSOCKBUF); |
300 | |
318 | |
301 | sprintf((char*)sl.buf,"delinv %d", op->count); |
319 | sprintf((char*)sl.buf,"delinv %d", op->count); |
302 | sl.len=strlen((char*)sl.buf); |
320 | sl.len=strlen((char*)sl.buf); |
… | |
… | |
312 | |
330 | |
313 | if (tmp->head) head = tmp->head; |
331 | if (tmp->head) head = tmp->head; |
314 | else head = tmp; |
332 | else head = tmp; |
315 | |
333 | |
316 | if (LOOK_OBJ(head)) { |
334 | if (LOOK_OBJ(head)) { |
317 | flags = query_flags (head); |
335 | add_object_to_socklist(&pl->contr->socket, &sl, head); |
318 | if (QUERY_FLAG(head, FLAG_NO_PICK)) |
|
|
319 | flags |= F_NOPICK; |
|
|
320 | if (!(pl->contr->socket.faces_sent[head->face->number] & NS_FACESENT_FACE)) |
|
|
321 | esrv_send_face(&pl->contr->socket, head->face->number,0); |
|
|
322 | if (QUERY_FLAG(head,FLAG_ANIMATE) && |
|
|
323 | !pl->contr->socket.anims_sent[head->animation_id]) |
|
|
324 | esrv_send_animation(&pl->contr->socket, head->animation_id); |
|
|
325 | SockList_AddInt(&sl, head->count); |
|
|
326 | SockList_AddInt(&sl, flags); |
|
|
327 | SockList_AddInt(&sl, QUERY_FLAG(head, FLAG_NO_PICK) ? -1 : WEIGHT(head)); |
|
|
328 | SockList_AddInt(&sl, head->face->number); |
|
|
329 | |
336 | |
330 | if (!head->custom_name) { |
|
|
331 | strncpy(item_n,query_base_name(head, 0),127); |
|
|
332 | item_n[127]=0; |
|
|
333 | len=strlen(item_n); |
|
|
334 | item_p=query_base_name(head, 1); |
|
|
335 | } else { |
|
|
336 | strncpy(item_n,head->custom_name,127); |
|
|
337 | item_n[127]=0; |
|
|
338 | len=strlen(item_n); |
|
|
339 | item_p=head->custom_name; |
|
|
340 | } |
|
|
341 | strncpy(item_n+len+1, item_p, 127); |
|
|
342 | item_n[254]=0; |
|
|
343 | len += strlen(item_n+1+len) + 1; |
|
|
344 | SockList_AddChar(&sl, (char) len); |
|
|
345 | memcpy(sl.buf+sl.len, item_n, len); |
|
|
346 | sl.len += len; |
|
|
347 | |
|
|
348 | SockList_AddShort(&sl,head->animation_id); |
|
|
349 | anim_speed=0; |
|
|
350 | if (QUERY_FLAG(head,FLAG_ANIMATE)) { |
|
|
351 | if (head->anim_speed) anim_speed=head->anim_speed; |
|
|
352 | else { |
|
|
353 | if (FABS(head->speed)<0.001) anim_speed=255; |
|
|
354 | else if (FABS(head->speed)>=1.0) anim_speed=1; |
|
|
355 | else anim_speed = (int) (1.0/FABS(head->speed)); |
|
|
356 | } |
|
|
357 | if (anim_speed>255) anim_speed=255; |
|
|
358 | } |
|
|
359 | SockList_AddChar(&sl, (char)anim_speed); |
|
|
360 | SockList_AddInt(&sl, head->nrof); |
|
|
361 | if (pl->contr->socket.itemcmd == 2) |
|
|
362 | SockList_AddShort(&sl, head->client_type); |
|
|
363 | SET_FLAG(head, FLAG_CLIENT_SENT); |
|
|
364 | got_one++; |
337 | got_one++; |
365 | |
338 | |
366 | /* IT is possible for players to accumulate a huge amount of |
339 | /* IT is possible for players to accumulate a huge amount of |
367 | * items (especially with some of the bags out there) to |
340 | * items (especially with some of the bags out there) to |
368 | * overflow the buffer. IF so, send multiple item commands. |
341 | * overflow the buffer. IF so, send multiple item commands. |
369 | */ |
342 | */ |
370 | if (sl.len > (MAXSOCKBUF-MAXITEMLEN)) { |
343 | if (sl.len >= (MAXSOCKBUF-MAXITEMLEN)) { |
371 | Send_With_Handling(&pl->contr->socket, &sl); |
344 | Send_With_Handling(&pl->contr->socket, &sl); |
372 | sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); |
345 | sprintf((char*)sl.buf,"item%d ", pl->contr->socket.itemcmd); |
373 | sl.len=strlen((char*)sl.buf); |
346 | sl.len=strlen((char*)sl.buf); |
374 | SockList_AddInt(&sl, op->count); |
347 | SockList_AddInt(&sl, op->count); |
375 | got_one=0; |
348 | got_one=0; |
… | |
… | |
426 | if (flags & UPD_FLAGS) |
399 | if (flags & UPD_FLAGS) |
427 | SockList_AddInt(&sl, query_flags(op)); |
400 | SockList_AddInt(&sl, query_flags(op)); |
428 | |
401 | |
429 | if (flags & UPD_WEIGHT) { |
402 | if (flags & UPD_WEIGHT) { |
430 | sint32 weight = WEIGHT(op); |
403 | sint32 weight = WEIGHT(op); |
431 | SockList_AddInt(&sl, weight); |
404 | |
|
|
405 | /* TRANSPORTS are odd - they sort of look like containers, yet can't be |
|
|
406 | * picked up. So we don't to send the weight, as it is odd that you see |
|
|
407 | * weight sometimes and not other (the draw_look won't send it |
|
|
408 | * for example. |
|
|
409 | */ |
|
|
410 | SockList_AddInt(&sl, QUERY_FLAG(op, FLAG_NO_PICK) ? -1 : weight); |
432 | if (pl == op) { |
411 | if (pl == op) { |
433 | op->contr->last_weight = weight; |
412 | op->contr->last_weight = weight; |
434 | } |
413 | } |
435 | } |
414 | } |
436 | |
415 | |
… | |
… | |
490 | /** |
469 | /** |
491 | * Sends item's info to player. |
470 | * Sends item's info to player. |
492 | */ |
471 | */ |
493 | void esrv_send_item(object *pl, object*op) |
472 | void esrv_send_item(object *pl, object*op) |
494 | { |
473 | { |
495 | int anim_speed, len; |
|
|
496 | SockList sl; |
474 | SockList sl; |
497 | char item_n[MAX_BUF]; |
|
|
498 | const char *item_p; |
|
|
499 | |
475 | |
500 | /* If this is not the player object, do some more checks */ |
476 | /* If this is not the player object, do some more checks */ |
501 | if (op!=pl) { |
477 | if (op!=pl) { |
502 | /* We only send 'visibile' objects to the client */ |
478 | /* We only send 'visibile' objects to the client */ |
503 | if (! LOOK_OBJ(op)) |
479 | if (! LOOK_OBJ(op)) |
… | |
… | |
518 | |
494 | |
519 | if (op->head) op=op->head; |
495 | if (op->head) op=op->head; |
520 | |
496 | |
521 | SockList_AddInt(&sl, op->env? op->env->count:0); |
497 | SockList_AddInt(&sl, op->env? op->env->count:0); |
522 | |
498 | |
523 | if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE)) |
499 | add_object_to_socklist(&pl->contr->socket, &sl, op); |
524 | esrv_send_face(&pl->contr->socket, op->face->number,0); |
|
|
525 | if (op->env && QUERY_FLAG(op,FLAG_ANIMATE) && |
|
|
526 | !pl->contr->socket.anims_sent[op->animation_id]) |
|
|
527 | esrv_send_animation(&pl->contr->socket, op->animation_id); |
|
|
528 | |
|
|
529 | SockList_AddInt(&sl, op->count); |
|
|
530 | SockList_AddInt(&sl, query_flags(op)); |
|
|
531 | SockList_AddInt(&sl, WEIGHT(op)); |
|
|
532 | SockList_AddInt(&sl, op->face->number); |
|
|
533 | |
|
|
534 | if(!op->custom_name) { |
|
|
535 | strncpy(item_n,query_base_name(op, 0),127); |
|
|
536 | item_n[127]=0; |
|
|
537 | len=strlen(item_n); |
|
|
538 | item_p=query_base_name(op, 1); |
|
|
539 | } else { |
|
|
540 | strncpy(item_n,op->custom_name,127); |
|
|
541 | item_n[127]=0; |
|
|
542 | len=strlen(item_n); |
|
|
543 | item_p=op->custom_name; |
|
|
544 | } |
|
|
545 | strncpy(item_n+len+1, item_p, 127); |
|
|
546 | item_n[254]=0; |
|
|
547 | len += strlen(item_n+1+len) + 1; |
|
|
548 | SockList_AddChar(&sl, (char)len); |
|
|
549 | memcpy(sl.buf+sl.len, item_n, len); |
|
|
550 | sl.len += len; |
|
|
551 | |
|
|
552 | SockList_AddShort(&sl,op->animation_id); |
|
|
553 | anim_speed=0; |
|
|
554 | if (QUERY_FLAG(op,FLAG_ANIMATE)) { |
|
|
555 | if (op->anim_speed) anim_speed=op->anim_speed; |
|
|
556 | else { |
|
|
557 | if (FABS(op->speed)<0.001) anim_speed=255; |
|
|
558 | else if (FABS(op->speed)>=1.0) anim_speed=1; |
|
|
559 | else anim_speed = (int) (1.0/FABS(op->speed)); |
|
|
560 | } |
|
|
561 | if (anim_speed>255) anim_speed=255; |
|
|
562 | } |
|
|
563 | SockList_AddChar(&sl, (char)anim_speed); |
|
|
564 | SockList_AddInt(&sl, op->nrof); |
|
|
565 | if (pl->contr->socket.itemcmd == 2) |
|
|
566 | SockList_AddShort(&sl, op->client_type); |
|
|
567 | |
500 | |
568 | Send_With_Handling(&pl->contr->socket, &sl); |
501 | Send_With_Handling(&pl->contr->socket, &sl); |
569 | SET_FLAG(op, FLAG_CLIENT_SENT); |
502 | SET_FLAG(op, FLAG_CLIENT_SENT); |
570 | free(sl.buf); |
503 | free(sl.buf); |
571 | } |
504 | } |
… | |
… | |
623 | return op; |
556 | return op; |
624 | else if (op->type == CONTAINER && pl->container == op) |
557 | else if (op->type == CONTAINER && pl->container == op) |
625 | for(tmp = op->inv; tmp; tmp = tmp->below) |
558 | for(tmp = op->inv; tmp; tmp = tmp->below) |
626 | if (tmp->count == count) |
559 | if (tmp->count == count) |
627 | return tmp; |
560 | return tmp; |
|
|
561 | |
|
|
562 | if (pl->contr->transport) { |
|
|
563 | for(tmp = pl->contr->transport->inv; tmp; tmp = tmp->below) |
|
|
564 | if (tmp->count == count) |
|
|
565 | return tmp; |
|
|
566 | } |
628 | return NULL; |
567 | return NULL; |
629 | } |
568 | } |
630 | |
569 | |
631 | |
570 | |
632 | /** Client wants to examine some object. So lets do so. */ |
571 | /** Client wants to examine some object. So lets do so. */ |
… | |
… | |
718 | object *tmp; |
657 | object *tmp; |
719 | int flag=0; |
658 | int flag=0; |
720 | sint16 x,y; |
659 | sint16 x,y; |
721 | mapstruct *m; |
660 | mapstruct *m; |
722 | |
661 | |
723 | |
|
|
724 | if (out_of_map(op->map, op->x+dx, op->y+dy)) return; |
|
|
725 | |
|
|
726 | x = op->x + dx; |
662 | x = op->x + dx; |
727 | y = op->y + dy; |
663 | y = op->y + dy; |
|
|
664 | |
|
|
665 | if (out_of_map(op->map, x, y)) return; |
728 | |
666 | |
729 | m = get_map_from_coord(op->map, &x, &y); |
667 | m = get_map_from_coord(op->map, &x, &y); |
730 | if (!m) return; |
668 | if (!m) return; |
731 | |
669 | |
732 | for(tmp=get_map_ob(m, x ,y);tmp!=NULL&&tmp->above!=NULL; |
670 | for(tmp=get_map_ob(m, x ,y);tmp!=NULL&&tmp->above!=NULL; |
… | |
… | |
778 | if (!(cp=strchr(buf,' '))) { |
716 | if (!(cp=strchr(buf,' '))) { |
779 | return; |
717 | return; |
780 | } |
718 | } |
781 | dy=atoi(cp); |
719 | dy=atoi(cp); |
782 | |
720 | |
783 | if (FABS(dx)>MAP_CLIENT_X/2 || FABS(dy)>MAP_CLIENT_Y/2) |
721 | if (FABS(dx) > pl->socket.mapx / 2 || FABS(dy) > pl->socket.mapy / 2) |
784 | return; |
722 | return; |
785 | |
723 | |
786 | if(pl->blocked_los[dx+(pl->socket.mapx/2)][dy+(pl->socket.mapy/2)]) |
724 | if(pl->blocked_los[dx + pl->socket.mapx / 2][dy + pl->socket.mapy / 2]) |
787 | return; |
725 | return; |
|
|
726 | |
788 | look_at(pl->ob, dx, dy); |
727 | look_at(pl->ob, dx, dy); |
789 | } |
728 | } |
790 | |
729 | |
791 | /** Move an object to a new location */ |
730 | /** Move an object to a new location */ |
792 | void esrv_move_object (object *pl, tag_t to, tag_t tag, long nrof) |
731 | void esrv_move_object (object *pl, tag_t to, tag_t tag, long nrof) |
793 | { |
732 | { |
794 | object *op, *env; |
733 | object *op, *env; |
795 | |
734 | |
796 | op = esrv_get_ob_from_count(pl, tag); |
735 | op = esrv_get_ob_from_count(pl, tag); |
797 | if (!op) { |
736 | if (!op) { |
798 | LOG(llevDebug, "Player '%s' tried to move the unknown object (%ld)\n", |
737 | LOG(llevDebug, "Player '%s' tried to move an unknown object (%ld)\n", |
799 | pl->name, tag); |
738 | pl->name, tag); |
800 | return; |
739 | return; |
801 | } |
740 | } |
802 | |
741 | |
|
|
742 | /* If on a transport, you don't drop to the ground - you drop to the |
|
|
743 | * transport. |
|
|
744 | */ |
803 | if (!to) { /* drop it to the ground */ |
745 | if (!to && !pl->contr->transport) { /* drop it to the ground */ |
804 | /* LOG(llevDebug, "Drop it on the ground.\n");*/ |
746 | /* LOG(llevDebug, "Drop it on the ground.\n");*/ |
805 | |
747 | |
806 | if (op->map && !op->env) { |
748 | if (op->map && !op->env) { |
807 | /* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/ |
749 | /* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/ |
808 | return; |
750 | return; |
… | |
… | |
829 | pl->contr->count = nrof; |
771 | pl->contr->count = nrof; |
830 | pick_up(pl, op); |
772 | pick_up(pl, op); |
831 | return ; |
773 | return ; |
832 | } |
774 | } |
833 | /* If not dropped or picked up, we are putting it into a sack */ |
775 | /* If not dropped or picked up, we are putting it into a sack */ |
|
|
776 | if (pl->contr->transport) { |
|
|
777 | if (can_pick(pl, op) && transport_can_hold(pl->contr->transport, op, nrof)) { |
|
|
778 | put_object_in_sack (pl, pl->contr->transport, op, nrof); |
|
|
779 | } |
|
|
780 | } else { |
834 | env = esrv_get_ob_from_count(pl, to); |
781 | env = esrv_get_ob_from_count(pl, to); |
835 | if (!env) { |
782 | if (!env) { |
836 | LOG(llevDebug, |
783 | LOG(llevDebug, |
837 | "Player '%s' tried to move object to the unknown location (%d)\n", |
784 | "Player '%s' tried to move object to the unknown location (%d)\n", |
838 | pl->name, to); |
785 | pl->name, to); |
839 | return; |
786 | return; |
840 | } |
787 | } |
841 | /* put_object_in_sack presumes that necessary sanity checking |
788 | /* put_object_in_sack presumes that necessary sanity checking |
842 | * has already been done (eg, it can be picked up and fits in |
789 | * has already been done (eg, it can be picked up and fits in |
843 | * in a sack, so check for those things. We should also check |
790 | * in a sack, so check for those things. We should also check |
844 | * an make sure env is in fact a container for that matter. |
791 | * an make sure env is in fact a container for that matter. |
845 | */ |
792 | */ |
|
|
793 | if (env->type == CONTAINER |
846 | if (env->type == CONTAINER && can_pick(pl, op) && sack_can_hold(pl, env, op, nrof)) { |
794 | && can_pick(pl, op) && sack_can_hold(pl, env, op, nrof)) { |
847 | put_object_in_sack (pl, env, op, nrof); |
795 | put_object_in_sack (pl, env, op, nrof); |
|
|
796 | } |
848 | } |
797 | } |
849 | } |
798 | } |
850 | |
799 | |
851 | |
800 | |