ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/item.c
(Generate patch)

Comparing deliantra/server/socket/item.c (file contents):
Revision 1.1.1.1 by root, Fri Feb 3 07:14:44 2006 UTC vs.
Revision 1.3 by root, Sun Jun 11 20:43:35 2006 UTC

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.3 2006/06/11 20:43:35 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 */
140static 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
142void esrv_draw_look(object *pl) 206void 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 */
291void esrv_send_inventory(object *pl, object *op) 311void 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 */
493void esrv_send_item(object *pl, object*op) 472void 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. */
778 if (!(cp=strchr(buf,' '))) { 717 if (!(cp=strchr(buf,' '))) {
779 return; 718 return;
780 } 719 }
781 dy=atoi(cp); 720 dy=atoi(cp);
782 721
783 if (FABS(dx)>MAP_CLIENT_X/2 || FABS(dy)>MAP_CLIENT_Y/2) 722 if (FABS(dx) > pl->socket.mapx / 2 || FABS(dy) > pl->socket.mapy / 2)
784 return; 723 return;
785 724
786 if(pl->blocked_los[dx+(pl->socket.mapx/2)][dy+(pl->socket.mapy/2)]) 725 if(pl->blocked_los[dx + pl->socket.mapx / 2][dy + pl->socket.mapy / 2])
787 return; 726 return;
727
788 look_at(pl->ob, dx, dy); 728 look_at(pl->ob, dx, dy);
789} 729}
790 730
791/** Move an object to a new location */ 731/** Move an object to a new location */
792void esrv_move_object (object *pl, tag_t to, tag_t tag, long nrof) 732void esrv_move_object (object *pl, tag_t to, tag_t tag, long nrof)
793{ 733{
794 object *op, *env; 734 object *op, *env;
795 735
796 op = esrv_get_ob_from_count(pl, tag); 736 op = esrv_get_ob_from_count(pl, tag);
797 if (!op) { 737 if (!op) {
798 LOG(llevDebug, "Player '%s' tried to move the unknown object (%ld)\n", 738 LOG(llevDebug, "Player '%s' tried to move an unknown object (%ld)\n",
799 pl->name, tag); 739 pl->name, tag);
800 return; 740 return;
801 } 741 }
802 742
743 /* If on a transport, you don't drop to the ground - you drop to the
744 * transport.
745 */
803 if (!to) { /* drop it to the ground */ 746 if (!to && !pl->contr->transport) { /* drop it to the ground */
804/* LOG(llevDebug, "Drop it on the ground.\n");*/ 747/* LOG(llevDebug, "Drop it on the ground.\n");*/
805 748
806 if (op->map && !op->env) { 749 if (op->map && !op->env) {
807/* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/ 750/* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/
808 return; 751 return;
829 pl->contr->count = nrof; 772 pl->contr->count = nrof;
830 pick_up(pl, op); 773 pick_up(pl, op);
831 return ; 774 return ;
832 } 775 }
833 /* If not dropped or picked up, we are putting it into a sack */ 776 /* If not dropped or picked up, we are putting it into a sack */
777 if (pl->contr->transport) {
778 if (can_pick(pl, op) && transport_can_hold(pl->contr->transport, op, nrof)) {
779 put_object_in_sack (pl, pl->contr->transport, op, nrof);
780 }
781 } else {
834 env = esrv_get_ob_from_count(pl, to); 782 env = esrv_get_ob_from_count(pl, to);
835 if (!env) { 783 if (!env) {
836 LOG(llevDebug, 784 LOG(llevDebug,
837 "Player '%s' tried to move object to the unknown location (%d)\n", 785 "Player '%s' tried to move object to the unknown location (%d)\n",
838 pl->name, to); 786 pl->name, to);
839 return; 787 return;
840 } 788 }
841 /* put_object_in_sack presumes that necessary sanity checking 789 /* put_object_in_sack presumes that necessary sanity checking
842 * has already been done (eg, it can be picked up and fits in 790 * 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 791 * 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. 792 * an make sure env is in fact a container for that matter.
845 */ 793 */
794 if (env->type == CONTAINER
846 if (env->type == CONTAINER && can_pick(pl, op) && sack_can_hold(pl, env, op, nrof)) { 795 && can_pick(pl, op) && sack_can_hold(pl, env, op, nrof)) {
847 put_object_in_sack (pl, env, op, nrof); 796 put_object_in_sack (pl, env, op, nrof);
797 }
848 } 798 }
849} 799}
850 800
851 801

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines