1 | /* |
1 | /* |
2 | * static char *rcsid_object_c = |
2 | * static char *rcsid_object_c = |
3 | * "$Id: object.C,v 1.2 2006/08/25 17:11:52 root Exp $"; |
3 | * "$Id: object.C,v 1.7 2006/08/29 05:03:54 root Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
51 | #endif |
51 | #endif |
52 | |
52 | |
53 | object *objects; /* Pointer to the list of used objects */ |
53 | object *objects; /* Pointer to the list of used objects */ |
54 | object *free_objects; /* Pointer to the list of unused objects */ |
54 | object *free_objects; /* Pointer to the list of unused objects */ |
55 | object *active_objects; /* List of active objects that need to be processed */ |
55 | object *active_objects; /* List of active objects that need to be processed */ |
56 | |
|
|
57 | void (*object_free_callback)(object *ob); |
|
|
58 | |
56 | |
59 | short freearr_x[SIZEOFFREE]= |
57 | short freearr_x[SIZEOFFREE]= |
60 | {0,0,1,1,1,0,-1,-1,-1,0,1,2,2,2,2,2,1,0,-1,-2,-2,-2,-2,-2,-1, |
58 | {0,0,1,1,1,0,-1,-1,-1,0,1,2,2,2,2,2,1,0,-1,-2,-2,-2,-2,-2,-1, |
61 | 0,1,2,3,3,3,3,3,3,3,2,1,0,-1,-2,-3,-3,-3,-3,-3,-3,-3,-2,-1}; |
59 | 0,1,2,3,3,3,3,3,3,3,2,1,0,-1,-2,-3,-3,-3,-3,-3,-3,-3,-2,-1}; |
62 | short freearr_y[SIZEOFFREE]= |
60 | short freearr_y[SIZEOFFREE]= |
… | |
… | |
548 | op->slaying = NULL; |
546 | op->slaying = NULL; |
549 | op->skill = NULL; |
547 | op->skill = NULL; |
550 | op->msg = NULL; |
548 | op->msg = NULL; |
551 | op->materialname = NULL; |
549 | op->materialname = NULL; |
552 | op->lore = NULL; |
550 | op->lore = NULL; |
553 | op->current_weapon_script = NULL; |
|
|
554 | clear_object(op); |
551 | clear_object(op); |
555 | } |
552 | } |
556 | |
553 | |
557 | /* Zero the key_values on op, decrementing the shared-string |
554 | /* Zero the key_values on op, decrementing the shared-string |
558 | * refcounts and freeing the links. |
555 | * refcounts and freeing the links. |
… | |
… | |
581 | * clear_object() frees everything allocated by an object, and also |
578 | * clear_object() frees everything allocated by an object, and also |
582 | * clears all variables and flags to default settings. |
579 | * clears all variables and flags to default settings. |
583 | */ |
580 | */ |
584 | |
581 | |
585 | void clear_object(object *op) { |
582 | void clear_object(object *op) { |
586 | |
583 | op->clear (); |
587 | if (object_free_callback) |
|
|
588 | object_free_callback (op); |
|
|
589 | |
584 | |
590 | event *evt; |
585 | event *evt; |
591 | event *evt2; |
586 | event *evt2; |
592 | |
587 | |
593 | /* redo this to be simpler/more efficient. Was also seeing |
588 | /* redo this to be simpler/more efficient. Was also seeing |
… | |
… | |
664 | |
659 | |
665 | void copy_object(object *op2, object *op) { |
660 | void copy_object(object *op2, object *op) { |
666 | int is_freed=QUERY_FLAG(op,FLAG_FREED),is_removed=QUERY_FLAG(op,FLAG_REMOVED); |
661 | int is_freed=QUERY_FLAG(op,FLAG_FREED),is_removed=QUERY_FLAG(op,FLAG_REMOVED); |
667 | event *evt, *evt2, *evt_new; |
662 | event *evt, *evt2, *evt_new; |
668 | |
663 | |
669 | if (object_free_callback) |
664 | op->clear (); |
670 | object_free_callback (op); |
|
|
671 | |
|
|
672 | // callback registries and self are empty for copied objects |
|
|
673 | // this ought to change in the future |
|
|
674 | |
665 | |
675 | /* Decrement the refcounts, but don't bother zeroing the fields; |
666 | /* Decrement the refcounts, but don't bother zeroing the fields; |
676 | they'll be overwritten by memcpy. */ |
667 | they'll be overwritten by memcpy. */ |
677 | if(op->name!=NULL) free_string(op->name); |
668 | if(op->name!=NULL) free_string(op->name); |
678 | if(op->name_pl!=NULL) free_string(op->name_pl); |
669 | if(op->name_pl!=NULL) free_string(op->name_pl); |
… | |
… | |
698 | op->events = NULL; |
689 | op->events = NULL; |
699 | |
690 | |
700 | free_key_values(op); |
691 | free_key_values(op); |
701 | |
692 | |
702 | *(object_special *)op = *(object_special *)op2; |
693 | *(object_special *)op = *(object_special *)op2; |
|
|
694 | op2->clone (op); |
703 | |
695 | |
704 | if(is_freed) SET_FLAG(op,FLAG_FREED); |
696 | if(is_freed) SET_FLAG(op,FLAG_FREED); |
705 | if(is_removed) SET_FLAG(op,FLAG_REMOVED); |
697 | if(is_removed) SET_FLAG(op,FLAG_REMOVED); |
706 | if(op->name!=NULL) add_refcount(op->name); |
698 | if(op->name!=NULL) add_refcount(op->name); |
707 | if(op->name_pl!=NULL) add_refcount(op->name_pl); |
699 | if(op->name_pl!=NULL) add_refcount(op->name_pl); |
… | |
… | |
1072 | free_object2(ob, 0); |
1064 | free_object2(ob, 0); |
1073 | } |
1065 | } |
1074 | void free_object2(object *ob, int free_inventory) { |
1066 | void free_object2(object *ob, int free_inventory) { |
1075 | object *tmp,*op; |
1067 | object *tmp,*op; |
1076 | |
1068 | |
1077 | if (object_free_callback) |
1069 | ob->clear (); |
1078 | object_free_callback (ob); |
|
|
1079 | |
1070 | |
1080 | if (!QUERY_FLAG(ob,FLAG_REMOVED)) { |
1071 | if (!QUERY_FLAG(ob,FLAG_REMOVED)) { |
1081 | LOG(llevDebug,"Free object called with non removed object\n"); |
1072 | LOG(llevDebug,"Free object called with non removed object\n"); |
1082 | dump_object(ob); |
1073 | dump_object(ob); |
1083 | #ifdef MANY_CORES |
1074 | #ifdef MANY_CORES |
… | |
… | |
2647 | if (tempfile == NULL) |
2638 | if (tempfile == NULL) |
2648 | { |
2639 | { |
2649 | LOG(llevError,"Error - Unable to read object temp file\n"); |
2640 | LOG(llevError,"Error - Unable to read object temp file\n"); |
2650 | return NULL; |
2641 | return NULL; |
2651 | }; |
2642 | }; |
|
|
2643 | object_thawer thawer (tempfile); |
2652 | load_object(tempfile,op,LO_NEWFILE,0); |
2644 | load_object(thawer,op,LO_NEWFILE,0); |
2653 | LOG(llevDebug," load str completed, object=%s\n",op->name); |
2645 | LOG(llevDebug," load str completed, object=%s\n",op->name); |
2654 | CLEAR_FLAG(op,FLAG_REMOVED); |
2646 | CLEAR_FLAG(op,FLAG_REMOVED); |
2655 | fclose(tempfile); |
2647 | fclose(tempfile); |
2656 | return op; |
2648 | return op; |
2657 | } |
2649 | } |