ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
(Generate patch)

Comparing deliantra/server/common/object.C (file contents):
Revision 1.29 by root, Mon Sep 11 12:38:36 2006 UTC vs.
Revision 1.30 by root, Mon Sep 11 20:28:37 2006 UTC

443 * Changed 2004-02-12 - if the player is setting at the play again 443 * Changed 2004-02-12 - if the player is setting at the play again
444 * prompt, he is removed, and we don't want to treat him as an owner of 444 * prompt, he is removed, and we don't want to treat him as an owner of
445 * anything, so check removed flag. I don't expect that this should break 445 * anything, so check removed flag. I don't expect that this should break
446 * anything - once an object is removed, it is basically dead anyways. 446 * anything - once an object is removed, it is basically dead anyways.
447 */ 447 */
448
449object * 448object *
450get_owner (object *op) 449object::get_owner ()
451{ 450{
452 if (op->owner == NULL) 451 if (!owner
453 return NULL; 452 || QUERY_FLAG (owner, FLAG_FREED)
453 || QUERY_FLAG (owner, FLAG_REMOVED))
454 owner = 0;
454 455
455 if (!QUERY_FLAG (op->owner, FLAG_FREED) && !QUERY_FLAG (op->owner, FLAG_REMOVED) && op->owner->count == op->ownercount)
456 return op->owner; 456 return owner;
457
458 op->owner = NULL;
459 op->ownercount = 0;
460 return NULL;
461}
462
463void
464clear_owner (object *op)
465{
466 if (!op)
467 return;
468
469 if (op->owner && op->ownercount == op->owner->count)
470 op->owner->refcount--;
471
472 op->owner = NULL;
473 op->ownercount = 0;
474} 457}
475 458
476/* 459/*
477 * Sets the owner and sets the skill and exp pointers to owner's current 460 * Sets the owner and sets the skill and exp pointers to owner's current
478 * skill and experience objects. 461 * skill and experience objects.
479 */ 462 */
480void 463void
481set_owner (object *op, object *owner) 464object::set_owner (object *owner)
482{ 465{
483 if (owner == NULL || op == NULL) 466 if (!owner)
484 return; 467 return;
485 468
486 /* next line added to allow objects which own objects */ 469 /* next line added to allow objects which own objects */
487 /* Add a check for ownercounts in here, as I got into an endless loop 470 /* Add a check for ownercounts in here, as I got into an endless loop
488 * with the fireball owning a poison cloud which then owned the 471 * with the fireball owning a poison cloud which then owned the
489 * fireball. I believe that was caused by one of the objects getting 472 * fireball. I believe that was caused by one of the objects getting
490 * freed and then another object replacing it. Since the ownercounts 473 * freed and then another object replacing it. Since the ownercounts
491 * didn't match, this check is valid and I believe that cause is valid. 474 * didn't match, this check is valid and I believe that cause is valid.
492 */ 475 */
493 while (owner->owner && owner != owner->owner && owner->ownercount == owner->owner->count) 476 while (owner->owner)
494 owner = owner->owner; 477 owner = owner->owner;
495 478
496 /* IF the owner still has an owner, we did not resolve to a final owner.
497 * so lets not add to that.
498 */
499 if (owner->owner)
500 return;
501
502 op->owner = owner; 479 this->owner = owner;
503
504 op->ownercount = owner->count;
505 owner->refcount++;
506}
507
508/* Set the owner to clone's current owner and set the skill and experience
509 * objects to clone's objects (typically those objects that where the owner's
510 * current skill and experience objects at the time when clone's owner was
511 * set - not the owner's current skill and experience objects).
512 *
513 * Use this function if player created an object (e.g. fire bullet, swarm
514 * spell), and this object creates further objects whose kills should be
515 * accounted for the player's original skill, even if player has changed
516 * skills meanwhile.
517 */
518void
519copy_owner (object *op, object *clone)
520{
521 object *owner = get_owner (clone);
522
523 if (owner == NULL)
524 {
525 /* players don't have owners - they own themselves. Update
526 * as appropriate.
527 */
528 if (clone->type == PLAYER)
529 owner = clone;
530 else
531 return;
532 }
533
534 set_owner (op, owner);
535} 480}
536 481
537/* Zero the key_values on op, decrementing the shared-string 482/* Zero the key_values on op, decrementing the shared-string
538 * refcounts and freeing the links. 483 * refcounts and freeing the links.
539 */ 484 */
555{ 500{
556 attachable_base::clear (); 501 attachable_base::clear ();
557 502
558 free_key_values (this); 503 free_key_values (this);
559 504
560 clear_owner (this); 505 owner = 0;
561
562 name = 0; 506 name = 0;
563 name_pl = 0; 507 name_pl = 0;
564 title = 0; 508 title = 0;
565 race = 0; 509 race = 0;
566 slaying = 0; 510 slaying = 0;
567 skill = 0; 511 skill = 0;
568 msg = 0; 512 msg = 0;
569 lore = 0; 513 lore = 0;
570 custom_name = 0; 514 custom_name = 0;
571 materialname = 0; 515 materialname = 0;
516 contr = 0;
517 below = 0;
518 above = 0;
519 inv = 0;
520 container = 0;
521 env = 0;
522 more = 0;
523 head = 0;
524 map = 0;
525 active_next = 0;
526 active_prev = 0;
572 527
573 memset (static_cast < object_pod * >(this), 0, sizeof (object_pod)); 528 memset (static_cast<object_pod *>(this), 0, sizeof (object_pod));
574 529
575 SET_FLAG (this, FLAG_REMOVED); 530 SET_FLAG (this, FLAG_REMOVED);
531
532 /* What is not cleared is next, prev, and count */
533
534 expmul = 1.0;
535 face = blank_face;
536 attacked_by_count = -1;
537
538 if (settings.casting_time)
539 casting_time = -1;
576} 540}
577 541
578void object::clone (object *destination) 542void object::clone (object *destination)
579{ 543{
580 *(object_copy *) destination = *this; 544 *(object_copy *)destination = *this;
581 *(object_pod *) destination = *this; 545 *(object_pod *)destination = *this;
582 546
583 if (self || cb) 547 if (self || cb)
584 INVOKE_OBJECT (CLONE, this, ARG_OBJECT (destination)); 548 INVOKE_OBJECT (CLONE, this, ARG_OBJECT (destination));
585}
586
587/*
588 * clear_object() frees everything allocated by an object, and also
589 * clears all variables and flags to default settings.
590 */
591
592void
593clear_object (object *op)
594{
595 op->clear ();
596
597 op->contr = NULL;
598 op->below = NULL;
599 op->above = NULL;
600 op->inv = NULL;
601 op->container = NULL;
602 op->env = NULL;
603 op->more = NULL;
604 op->head = NULL;
605 op->map = NULL;
606 op->refcount = 0;
607 op->active_next = NULL;
608 op->active_prev = NULL;
609 /* What is not cleared is next, prev, and count */
610
611 op->expmul = 1.0;
612 op->face = blank_face;
613 op->attacked_by_count = -1;
614
615 if (settings.casting_time)
616 op->casting_time = -1;
617} 549}
618 550
619/* 551/*
620 * copy object first frees everything allocated by the second object, 552 * copy object first frees everything allocated by the second object,
621 * and then copies the contends of the first object into the second 553 * and then copies the contends of the first object into the second
622 * object, allocating what needs to be allocated. Basically, any 554 * object, allocating what needs to be allocated. Basically, any
623 * data that is malloc'd needs to be re-malloc/copied. Otherwise, 555 * data that is malloc'd needs to be re-malloc/copied. Otherwise,
624 * if the first object is freed, the pointers in the new object 556 * if the first object is freed, the pointers in the new object
625 * will point at garbage. 557 * will point at garbage.
626 */ 558 */
627
628void 559void
629copy_object (object *op2, object *op) 560copy_object (object *op2, object *op)
630{ 561{
631 bool is_freed = QUERY_FLAG (op, FLAG_FREED); 562 bool is_freed = QUERY_FLAG (op, FLAG_FREED);
632 bool is_removed = QUERY_FLAG (op, FLAG_REMOVED); 563 bool is_removed = QUERY_FLAG (op, FLAG_REMOVED);
901 832
902 if (op->more != NULL) 833 if (op->more != NULL)
903 update_object (op->more, action); 834 update_object (op->more, action);
904} 835}
905 836
906static unordered_vector < object *>mortals; 837static unordered_vector<object *> mortals;
907static 838static std::vector<object *> freed;
908std::vector < object *>
909 freed;
910 839
911void object::free_mortals () 840void object::free_mortals ()
912{ 841{
913 for (unordered_vector < object *>::iterator i = mortals.begin (); i != mortals.end ();) 842 for (unordered_vector<object *>::iterator i = mortals.begin (); i != mortals.end ();)
914 if (!(*i)->refcount) 843 if ((*i)->refcnt)
844 ++i; // further delay freeing
845 else
915 { 846 {
916 freed.push_back (*i); 847 freed.push_back (*i);//D
848 //delete *i;
917 mortals.erase (i); 849 mortals.erase (i);
918 } 850 }
919 else 851
920 ++i; 852 if (mortals.size())//D
853 LOG (llevDebug, "%d objects in mortal queue\n", mortals.size());//D
921} 854}
922 855
923object::object () 856object::object ()
924{ 857{
925 SET_FLAG (this, FLAG_REMOVED); 858 SET_FLAG (this, FLAG_REMOVED);
973 object * 906 object *
974 op; 907 op;
975 908
976 if (freed.empty ()) 909 if (freed.empty ())
977 op = new object; 910 op = new object;
978
979 else 911 else
980 { 912 {
981 // highly annoying, but the only way to get it stable right now 913 // highly annoying, but the only way to get it stable right now
982 op = freed.back (); 914 op = freed.back ();
983 freed.pop_back (); 915 freed.pop_back ();
1058 op = tmp; 990 op = tmp;
1059 } 991 }
1060 } 992 }
1061 } 993 }
1062 994
1063 clear_owner (this); 995 owner = 0;
1064 996
1065 /* Remove object from the active list */ 997 /* Remove object from the active list */
1066 speed = 0; 998 speed = 0;
1067 update_ob_speed (this); 999 update_ob_speed (this);
1068 1000

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines