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.63 by root, Thu Apr 24 00:30:52 2008 UTC vs.
Revision 1.64 by root, Mon May 5 22:03:22 2008 UTC

322 sl << uint16 (head->client_type); 322 sl << uint16 (head->client_type);
323 323
324 SET_FLAG (head, FLAG_CLIENT_SENT); 324 SET_FLAG (head, FLAG_CLIENT_SENT);
325} 325}
326 326
327static faceidx
328need_face_now (player *pl, const char *name)
329{
330 faceidx face = face_find (name, empty_face);
331
332 pl->ns->send_face (face, -50);
333 pl->ns->flush_fx ();
334
335 return face;
336}
337
338#define FINGER_UP "finger_up.x11"
339#define FINGER_DOWN "finger_down.x11"
340
327/** 341/**
328 * Send the look window. Don't need to do animations here 342 * Send the look window. Don't need to do animations here
329 * This sends all the faces to the client, not just updates. This is 343 * This sends all the faces to the client, not just updates. This is
330 * because object ordering would otherwise be inconsistent. 344 * because object ordering would otherwise be inconsistent.
331 */ 345 */
332void 346void
333esrv_draw_look (player *pl) 347esrv_draw_look (player *pl)
334{ 348{
335 int got_one = 0, start_look = 0, end_look = 0;
336
337 object *ob = pl->ob; 349 object *ob = pl->ob;
338 350
339 if (!pl->ns->update_look) 351 if (!pl->ns->update_look)
340 { 352 {
341 LOG (llevDebug, "esrv_draw_look called when update_look was not set (player %s)\n", &ob->name); 353 LOG (llevDebug, "esrv_draw_look called when update_look was not set (player %s)\n", &ob->name);
355 packet sl; 367 packet sl;
356 sl.printf ("item%d ", pl->ns->itemcmd); 368 sl.printf ("item%d ", pl->ns->itemcmd);
357 369
358 sl << uint32 (0); 370 sl << uint32 (0);
359 371
360 pl->ns->send_face (empty_face, -50); 372 int start_pos = pl->ns->look_position;
361 pl->ns->flush_fx (); 373 bool dirty = false;
362 374
363 if (pl->ns->look_position) 375 mapspace &ms = ob->ms ();
376
377 // manage a ring buffer of the "last FLOORBOX_PAGESIZE" items and
378 // start from the top
379 object *items [FLOORBOX_PAGESIZE];
380 int item_idx = 0, item_cnt = 0;
381 int pos = 0;
382
383 // find our items by walking down
384 object *item = ms.top;
385
386 for (; item && item_cnt < FLOORBOX_PAGESIZE; item = item->below)
387 {
388 if (!item->client_visible ())
389 continue;
390
391 if (++pos < start_pos)
392 continue;
393
394 // record item
395 items [item_idx] = item; item_idx = item_idx < FLOORBOX_PAGESIZE ? item_idx + 1 : 0;
396 item_cnt++;
397
398 // stop at first floor
399 if (item->flag [FLAG_IS_FLOOR])
400 {
401 // we are finished, don't append "next group of items"
402 // by setting item to ms.bot it becomes zero which is checked after the while loop
403 item = ms.bot;
404 }
364 { 405 }
365 char buf[80];
366 snprintf (buf, 80, "Apply this to see %d previous items", FLOORBOX_PAGESIZE);
367 406
407 // see if there are more if we cared - we ignore invisible objects
408 if (item)
409 {
410 /* What we basically do is make a 'fake' object - when the user applies it,
411 * we notice the special tag the object has, and act accordingly.
412 */
368 sl << uint32 (0x80000000 | (pl->ns->look_position - FLOORBOX_PAGESIZE)) 413 sl << uint32 (0x80000000 | (start_pos + FLOORBOX_PAGESIZE))
369 << uint32 (0) 414 << uint32 (0)
370 << sint32 (-1) 415 << uint32 ((uint32) - 1)
371 << uint32 (empty_face) 416 << uint32 (need_face_now (pl, FINGER_DOWN))
372 << data8 (buf) 417 << data8 ("Apply this to see the items below")
373 << uint16 (0) 418 << uint16 (0)
374 << uint8 (0) 419 << uint8 (0)
375 << uint32 (0); 420 << uint32 (0);
376 421
377 if (pl->ns->itemcmd == 2) 422 if (pl->ns->itemcmd == 2)
378 sl << uint16 (0); 423 sl << uint16 (0);
379 }
380 424
381 object *tmp = ob->ms ().top; 425 dirty = true;
382 for (object *last = 0; tmp != last; tmp = tmp->below)
383 { 426 }
384 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR) && !last) 427
428 // now send out all items in the ring buffer in reverse order
429 while (item_cnt)
430 {
431 --item_cnt;
432 item_idx = (item_idx ? item_idx : FLOORBOX_PAGESIZE) - 1;
433 object *item = items [item_idx];
434
435 add_object_to_socklist (*pl->ns, sl, item->head_ ());
436
437 dirty = true;
438
439 // if packet got too large, send it and begin a new one
440 if (sl.length () > MAXSOCKBUF - MAXITEMLEN)
385 { 441 {
386 last = tmp->below; /* assumes double floor mode */ 442 pl->ns->send_packet (sl);
387 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR)) 443
388 last = last->below; 444 sl.reset ();
445 sl.printf ("item%d ", pl->ns->itemcmd);
446 sl << uint32 (0);
447
448 dirty = false;
389 } 449 }
390
391 if (tmp->client_visible ())
392 {
393 if (++start_look < pl->ns->look_position)
394 continue;
395
396 end_look++;
397
398 if (end_look > FLOORBOX_PAGESIZE)
399 {
400 /* What we basically do is make a 'fake' object - when the user applies it,
401 * we notice the special tag the object has, and act accordingly.
402 */
403 sl << uint32 (0x80000000 | (pl->ns->look_position + FLOORBOX_PAGESIZE))
404 << uint32 (0)
405 << uint32 ((uint32) - 1)
406 << uint32 (empty_face)
407 << data8 ("Apply this to see next group of items")
408 << uint16 (0)
409 << uint8 (0)
410 << uint32 (0);
411
412 if (pl->ns->itemcmd == 2)
413 sl << uint16 (0);
414
415 break;
416 }
417
418 add_object_to_socklist (*pl->ns, sl, tmp->head_ ());
419 got_one++;
420
421 if (sl.length () > MAXSOCKBUF - MAXITEMLEN)
422 {
423 pl->ns->send_packet (sl);
424
425 sl.reset ();
426 sl.printf ("item%d ", pl->ns->itemcmd);
427 sl << uint32 (0);
428 got_one = 0;
429 }
430 }
431 } 450 }
432 451
433 if (got_one) 452 if (start_pos)
453 {
454 sl << uint32 (0x80000000 | (start_pos - FLOORBOX_PAGESIZE))
455 << uint32 (0)
456 << sint32 (-1)
457 << uint32 (need_face_now (pl, FINGER_UP))
458 << data8 ("Apply this to see the items higher up")
459 << uint16 (0)
460 << uint8 (0)
461 << uint32 (0);
462
463 if (pl->ns->itemcmd == 2)
464 sl << uint16 (0);
465
466 dirty = true;
467 }
468
469 if (dirty)
434 pl->ns->send_packet (sl); 470 pl->ns->send_packet (sl);
435
436} 471}
437 472
438/** 473/**
439 * Sends whole inventory. 474 * Sends whole inventory.
440 */ 475 */
699void 734void
700ExamineCmd (char *buf, int len, player *pl) 735ExamineCmd (char *buf, int len, player *pl)
701{ 736{
702 tag_t tag = atoi (buf); 737 tag_t tag = atoi (buf);
703 738
739 /* If the high bit is set, player applied a pseudo object. */
740 if (tag & 0x80000000)
741 {
742 pl->ns->look_position = tag & 0x7fffffff;
743 pl->ns->floorbox_update ();
744 return;
745 }
746
704 object *op = esrv_get_ob_from_count (pl->ob, tag); 747 object *op = esrv_get_ob_from_count (pl->ob, tag);
705 748
706 if (!op) 749 if (!op)
707 { 750 {
708 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag); 751 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag);
732/** Client wants to apply some object. Lets do so. */ 775/** Client wants to apply some object. Lets do so. */
733void 776void
734ApplyCmd (char *buf, int len, player *pl) 777ApplyCmd (char *buf, int len, player *pl)
735{ 778{
736 tag_t tag = atoi (buf); 779 tag_t tag = atoi (buf);
737
738 /* sort of a hack, but if the player saves and the player then manually
739 * applies a savebed (or otherwise tries to do stuff), we run into trouble.
740 */
741 if (QUERY_FLAG (pl->ob, FLAG_REMOVED))
742 return;
743 780
744 /* If the high bit is set, player applied a pseudo object. */ 781 /* If the high bit is set, player applied a pseudo object. */
745 if (tag & 0x80000000) 782 if (tag & 0x80000000)
746 { 783 {
747 pl->ns->look_position = tag & 0x7fffffff; 784 pl->ns->look_position = tag & 0x7fffffff;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines