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.65 by root, Tue May 6 16:32:34 2008 UTC

253 * animation of face to the client. 253 * animation of face to the client.
254 */ 254 */
255static void 255static void
256add_object_to_socklist (client &ns, packet &sl, object *head) 256add_object_to_socklist (client &ns, packet &sl, object *head)
257{ 257{
258 int flags, len, anim_speed;
259 char item_n[MAX_BUF]; 258 char item_n[MAX_BUF];
260 const char *item_p; 259 const char *item_p;
261 260
262 flags = query_flags (head); 261 int flags = query_flags (head);
263 if (QUERY_FLAG (head, FLAG_NO_PICK)) 262 if (QUERY_FLAG (head, FLAG_NO_PICK))
264 flags |= F_NOPICK; 263 flags |= F_NOPICK;
265 264
266 ns.send_face (head->face, -50); 265 ns.send_face (head->face, -50);
267 ns.flush_fx (); 266 ns.flush_fx ();
272 sl << uint32 (head->count) 271 sl << uint32 (head->count)
273 << uint32 (flags) 272 << uint32 (flags)
274 << uint32 (QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : head->client_weight ()) 273 << uint32 (QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : head->client_weight ())
275 << uint32 (head->face); 274 << uint32 (head->face);
276 275
276 int len;
277
277 if (!head->custom_name) 278 if (!head->custom_name)
278 { 279 {
279 strncpy (item_n, query_base_name (head, 0), 127); 280 strncpy (item_n, query_base_name (head, 0), 127);
280 item_n[127] = 0; 281 item_n[127] = 0;
281 len = strlen (item_n); 282 len = strlen (item_n);
294 len += strlen (item_n + 1 + len) + 1; 295 len += strlen (item_n + 1 + len) + 1;
295 296
296 sl << data8 (item_n, len) 297 sl << data8 (item_n, len)
297 << uint16 (head->animation_id); 298 << uint16 (head->animation_id);
298 299
299 anim_speed = 0; 300 int anim_speed = !head->flag [FLAG_ANIMATE] ? 0
300 if (QUERY_FLAG (head, FLAG_ANIMATE)) 301 : head->anim_speed ? clamp (head->anim_speed, 1, 255)
301 { 302 : 1. / clamp (fabs (head->speed), 1./255., 1./1.);
302 if (head->anim_speed)
303 anim_speed = head->anim_speed;
304 else
305 {
306 if (fabs (head->speed) < 0.001)
307 anim_speed = 255;
308 else if (fabs (head->speed) >= 1.0)
309 anim_speed = 1;
310 else
311 anim_speed = (int) (1.0 / fabs (head->speed));
312 }
313
314 if (anim_speed > 255)
315 anim_speed = 255;
316 }
317 303
318 sl << uint8 (anim_speed) 304 sl << uint8 (anim_speed)
319 << uint32 (head->nrof); 305 << uint32 (head->nrof);
320 306
321 if (ns.itemcmd == 2) 307 if (ns.itemcmd == 2)
322 sl << uint16 (head->client_type); 308 sl << uint16 (head->client_type);
323 309
324 SET_FLAG (head, FLAG_CLIENT_SENT); 310 SET_FLAG (head, FLAG_CLIENT_SENT);
325} 311}
312
313static faceidx
314need_face_now (player *pl, const char *name)
315{
316 faceidx face = face_find (name, empty_face);
317
318 pl->ns->send_face (face, -50);
319 pl->ns->flush_fx ();
320
321 return face;
322}
323
324#define FINGER_UP "finger_up.x11"
325#define FINGER_DOWN "finger_down.x11"
326 326
327/** 327/**
328 * Send the look window. Don't need to do animations here 328 * 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 329 * This sends all the faces to the client, not just updates. This is
330 * because object ordering would otherwise be inconsistent. 330 * because object ordering would otherwise be inconsistent.
331 */ 331 */
332void 332void
333esrv_draw_look (player *pl) 333esrv_draw_look (player *pl)
334{ 334{
335 int got_one = 0, start_look = 0, end_look = 0;
336
337 object *ob = pl->ob; 335 object *ob = pl->ob;
338 336
339 if (!pl->ns->update_look) 337 if (!pl->ns->update_look)
340 { 338 {
341 LOG (llevDebug, "esrv_draw_look called when update_look was not set (player %s)\n", &ob->name); 339 LOG (llevDebug, "esrv_draw_look called when update_look was not set (player %s)\n", &ob->name);
355 packet sl; 353 packet sl;
356 sl.printf ("item%d ", pl->ns->itemcmd); 354 sl.printf ("item%d ", pl->ns->itemcmd);
357 355
358 sl << uint32 (0); 356 sl << uint32 (0);
359 357
360 pl->ns->send_face (empty_face, -50); 358 int start_pos = pl->ns->look_position;
361 pl->ns->flush_fx (); 359 bool dirty = false;
362 360
363 if (pl->ns->look_position) 361 mapspace &ms = ob->ms ();
362
363 // manage a ring buffer of the "last FLOORBOX_PAGESIZE" items and
364 // start from the top
365 object *items [FLOORBOX_PAGESIZE];
366 int item_idx = 0, item_cnt = 0;
367 int pos = 0;
368
369 // find our items by walking down
370 object *item = ms.top;
371
372 for (; item && item_cnt < FLOORBOX_PAGESIZE; item = item->below)
373 {
374 if (!item->client_visible ())
375 continue;
376
377 if (++pos < start_pos)
378 continue;
379
380 // record item
381 items [item_idx] = item; item_idx = item_idx < FLOORBOX_PAGESIZE ? item_idx + 1 : 0;
382 item_cnt++;
383
384 // stop at first floor
385 if (item->flag [FLAG_IS_FLOOR])
386 {
387 // we are finished, don't append "next group of items"
388 // by setting item to ms.bot it becomes zero which is checked after the while loop
389 item = ms.bot;
390 }
364 { 391 }
365 char buf[80];
366 snprintf (buf, 80, "Apply this to see %d previous items", FLOORBOX_PAGESIZE);
367 392
393 // see if there are more if we cared - we ignore invisible objects
394 if (item)
395 {
396 /* What we basically do is make a 'fake' object - when the user applies it,
397 * we notice the special tag the object has, and act accordingly.
398 */
368 sl << uint32 (0x80000000 | (pl->ns->look_position - FLOORBOX_PAGESIZE)) 399 sl << uint32 (0x80000000 | (start_pos + FLOORBOX_PAGESIZE))
369 << uint32 (0) 400 << uint32 (0)
370 << sint32 (-1) 401 << uint32 ((uint32) - 1)
371 << uint32 (empty_face) 402 << uint32 (need_face_now (pl, FINGER_DOWN))
372 << data8 (buf) 403 << data8 ("Apply this to see the items below")
373 << uint16 (0) 404 << uint16 (0)
374 << uint8 (0) 405 << uint8 (0)
375 << uint32 (0); 406 << uint32 (0);
376 407
377 if (pl->ns->itemcmd == 2) 408 if (pl->ns->itemcmd == 2)
378 sl << uint16 (0); 409 sl << uint16 (0);
379 }
380 410
381 object *tmp = ob->ms ().top; 411 dirty = true;
382 for (object *last = 0; tmp != last; tmp = tmp->below)
383 { 412 }
384 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR) && !last) 413
414 // now send out all items in the ring buffer in reverse order
415 while (item_cnt)
416 {
417 --item_cnt;
418 item_idx = (item_idx ? item_idx : FLOORBOX_PAGESIZE) - 1;
419 object *item = items [item_idx];
420
421 add_object_to_socklist (*pl->ns, sl, item->head_ ());
422
423 dirty = true;
424
425 // if packet got too large, send it and begin a new one
426 if (sl.length () > MAXSOCKBUF - MAXITEMLEN)
385 { 427 {
386 last = tmp->below; /* assumes double floor mode */ 428 pl->ns->send_packet (sl);
387 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR)) 429
388 last = last->below; 430 sl.reset ();
431 sl.printf ("item%d ", pl->ns->itemcmd);
432 sl << uint32 (0);
433
434 dirty = false;
389 } 435 }
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 } 436 }
432 437
433 if (got_one) 438 if (start_pos)
439 {
440 sl << uint32 (0x80000000 | (start_pos - FLOORBOX_PAGESIZE))
441 << uint32 (0)
442 << sint32 (-1)
443 << uint32 (need_face_now (pl, FINGER_UP))
444 << data8 ("Apply this to see the items higher up")
445 << uint16 (0)
446 << uint8 (0)
447 << uint32 (0);
448
449 if (pl->ns->itemcmd == 2)
450 sl << uint16 (0);
451
452 dirty = true;
453 }
454
455 if (dirty)
434 pl->ns->send_packet (sl); 456 pl->ns->send_packet (sl);
435
436} 457}
437 458
438/** 459/**
439 * Sends whole inventory. 460 * Sends whole inventory.
440 */ 461 */
699void 720void
700ExamineCmd (char *buf, int len, player *pl) 721ExamineCmd (char *buf, int len, player *pl)
701{ 722{
702 tag_t tag = atoi (buf); 723 tag_t tag = atoi (buf);
703 724
725 /* If the high bit is set, player applied a pseudo object. */
726 if (tag & 0x80000000)
727 {
728 pl->ns->look_position = tag & 0x7fffffff;
729 pl->ns->floorbox_update ();
730 return;
731 }
732
704 object *op = esrv_get_ob_from_count (pl->ob, tag); 733 object *op = esrv_get_ob_from_count (pl->ob, tag);
705 734
706 if (!op) 735 if (!op)
707 { 736 {
708 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag); 737 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. */ 761/** Client wants to apply some object. Lets do so. */
733void 762void
734ApplyCmd (char *buf, int len, player *pl) 763ApplyCmd (char *buf, int len, player *pl)
735{ 764{
736 tag_t tag = atoi (buf); 765 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 766
744 /* If the high bit is set, player applied a pseudo object. */ 767 /* If the high bit is set, player applied a pseudo object. */
745 if (tag & 0x80000000) 768 if (tag & 0x80000000)
746 { 769 {
747 pl->ns->look_position = tag & 0x7fffffff; 770 pl->ns->look_position = tag & 0x7fffffff;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines