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.19 by root, Fri Sep 8 17:14:07 2006 UTC vs.
Revision 1.23 by root, Sun Sep 10 14:54:02 2006 UTC

1/* 1/*
2 * static char *rcsid_object_c = 2 * static char *rcsid_object_c =
3 * "$Id: object.C,v 1.19 2006/09/08 17:14:07 root Exp $"; 3 * "$Id: object.C,v 1.23 2006/09/10 14:54:02 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
54 {0,9,10,13,14,17,18,21,22,25,26,27,30,31,32,33,36,37,39,39,42,43,44,45, 54 {0,9,10,13,14,17,18,21,22,25,26,27,30,31,32,33,36,37,39,39,42,43,44,45,
55 48,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49}; 55 48,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49};
56int freedir[SIZEOFFREE]= { 56int freedir[SIZEOFFREE]= {
57 0,1,2,3,4,5,6,7,8,1,2,2,2,3,4,4,4,5,6,6,6,7,8,8,8, 57 0,1,2,3,4,5,6,7,8,1,2,2,2,3,4,4,4,5,6,6,6,7,8,8,8,
58 1,2,2,2,2,2,3,4,4,4,4,4,5,6,6,6,6,6,7,8,8,8,8,8}; 58 1,2,2,2,2,2,3,4,4,4,4,4,5,6,6,6,6,6,7,8,8,8,8,8};
59
60 59
61/* Returns TRUE if every key_values in wants has a partner with the same value in has. */ 60/* Returns TRUE if every key_values in wants has a partner with the same value in has. */
62static int compare_ob_value_lists_one(const object * wants, const object * has) { 61static int compare_ob_value_lists_one(const object * wants, const object * has) {
63 key_value * wants_field; 62 key_value * wants_field;
64 63
530 SET_FLAG (this, FLAG_REMOVED); 529 SET_FLAG (this, FLAG_REMOVED);
531} 530}
532 531
533void object::clone (object *destination) 532void object::clone (object *destination)
534{ 533{
535 *(object_copy *)destination = *(object_copy *)this; 534 *(object_copy *)destination = *this;
536 *(object_pod *)destination = *(object_pod *)this; 535 *(object_pod *)destination = *this;
537 536
538 if (self || cb) 537 if (self || cb)
539 INVOKE_OBJECT (CLONE, this, ARG_OBJECT (destination)); 538 INVOKE_OBJECT (CLONE, this, ARG_OBJECT (destination));
540} 539}
541 540
591 590
592 if (op2->speed < 0) 591 if (op2->speed < 0)
593 op->speed_left = op2->speed_left - RANDOM() % 200 / 100.0; 592 op->speed_left = op2->speed_left - RANDOM() % 200 / 100.0;
594 593
595 /* Copy over key_values, if any. */ 594 /* Copy over key_values, if any. */
596 if (op2->key_values != NULL) 595 if (op2->key_values)
597 { 596 {
598 key_value *tail = NULL; 597 key_value *tail = 0;
599 key_value *i; 598 key_value *i;
600 599
601 op->key_values = NULL; 600 op->key_values = 0;
602 601
603 for (i = op2->key_values; i != NULL; i = i->next) 602 for (i = op2->key_values; i; i = i->next)
604 { 603 {
605 key_value *new_link = new key_value; 604 key_value *new_link = new key_value;
606 605
607 new_link->next = NULL; 606 new_link->next = 0;
608 new_link->key = i->key; 607 new_link->key = i->key;
609 new_link->value = i->value; 608 new_link->value = i->value;
610 609
611 /* Try and be clever here, too. */ 610 /* Try and be clever here, too. */
612 if (op->key_values == NULL) 611 if (!op->key_values)
613 { 612 {
614 op->key_values = new_link; 613 op->key_values = new_link;
615 tail = new_link; 614 tail = new_link;
616 } 615 }
617 else 616 else
621 } 620 }
622 } 621 }
623 } 622 }
624 623
625 update_ob_speed (op); 624 update_ob_speed (op);
626}
627
628object::object ()
629{
630 count = ++ob_count;
631
632 next = objects;
633
634 if (objects)
635 objects->prev = this;
636
637 objects = this;
638
639 SET_FLAG (this, FLAG_REMOVED);
640
641 expmul = 1.0;
642 face = blank_face;
643 attacked_by_count = -1;
644}
645
646object::~object ()
647{
648} 625}
649 626
650/* 627/*
651 * If an object with the IS_TURNABLE() flag needs to be turned due 628 * If an object with the IS_TURNABLE() flag needs to be turned due
652 * to the closest player being on the other side, this function can 629 * to the closest player being on the other side, this function can
816 update_now=1; 793 update_now=1;
817 794
818 if (QUERY_FLAG(op, FLAG_ALIVE) && !(flags & P_IS_ALIVE)) 795 if (QUERY_FLAG(op, FLAG_ALIVE) && !(flags & P_IS_ALIVE))
819 update_now=1; 796 update_now=1;
820 797
798 if (op->type == SAFE_GROUND && !(flags & P_SAFE))
799 update_now=1;
800
821 if ((move_on | op->move_on) != move_on) update_now=1; 801 if ((move_on | op->move_on) != move_on) update_now=1;
802
822 if ((move_off | op->move_off) != move_off) update_now=1; 803 if ((move_off | op->move_off) != move_off) update_now=1;
804
823 /* This isn't perfect, but I don't expect a lot of objects to 805 /* This isn't perfect, but I don't expect a lot of objects to
824 * to have move_allow right now. 806 * to have move_allow right now.
825 */ 807 */
826 if (((move_block | op->move_block) & ~op->move_allow) != move_block) 808 if (((move_block | op->move_block) & ~op->move_allow) != move_block)
827 update_now=1; 809 update_now=1;
810
828 if ((move_slow | op->move_slow) != move_slow) update_now=1; 811 if ((move_slow | op->move_slow) != move_slow)
812 update_now=1;
829 } 813 }
830 /* if the object is being removed, we can't make intelligent 814 /* if the object is being removed, we can't make intelligent
831 * decisions, because remove_ob can't really pass the object 815 * decisions, because remove_ob can't really pass the object
832 * that is being removed. 816 * that is being removed.
833 */ 817 */
847 831
848 if(op->more!=NULL) 832 if(op->more!=NULL)
849 update_object(op->more, action); 833 update_object(op->more, action);
850} 834}
851 835
836static std::vector<object *> mortals;
837
838void object::free_mortals ()
839{
840 for (std::vector<object *>::iterator i = mortals.begin (); i != mortals.end (); ++i)
841 delete *i;
842
843 mortals.clear ();
844}
845
846object::object ()
847{
848 SET_FLAG (this, FLAG_REMOVED);
849
850 expmul = 1.0;
851 face = blank_face;
852 attacked_by_count = -1;
853}
854
855object::~object ()
856{
857 free_key_values (this);
858}
859
860void
861object::link ()
862{
863 count = ++ob_count;
864
865 prev = 0;
866 next = objects;
867
868 if (objects)
869 objects->prev = this;
870
871 objects = this;
872}
873
874void
875object::unlink ()
876{
877 count = 0;
878
879 /* Remove this object from the list of used objects */
880 if (prev) prev->next = next;
881 if (next) next->prev = prev;
882 if (this == objects) objects = next;
883}
884
885object *object::create ()
886{
887 object *op = new object;
888 op->link ();
889 return op;
890}
852 891
853/* 892/*
854 * free_object() frees everything allocated by an object, removes 893 * free_object() frees everything allocated by an object, removes
855 * it from the list of used objects, and puts it on the list of 894 * it from the list of used objects, and puts it on the list of
856 * free objects. The IS_FREED() flag is set in the object. 895 * free objects. The IS_FREED() flag is set in the object.
858 * this function to succeed. 897 * this function to succeed.
859 * 898 *
860 * If free_inventory is set, free inventory as well. Else drop items in 899 * If free_inventory is set, free inventory as well. Else drop items in
861 * inventory to the ground. 900 * inventory to the ground.
862 */ 901 */
863
864void 902void
865free_object (object * ob) 903object::free (bool free_inventory)
866{ 904{
867 free_object2 (ob, 0);
868}
869
870void
871free_object2 (object * ob, int free_inventory)
872{
873 object *tmp, *op;
874
875 if (!QUERY_FLAG (ob, FLAG_REMOVED)) 905 if (!QUERY_FLAG (this, FLAG_REMOVED))
876 { 906 {
877 LOG (llevDebug, "Free object called with non removed object\n"); 907 LOG (llevDebug, "Free object called with non removed object\n");
878 dump_object (ob); 908 dump_object (this);
879#ifdef MANY_CORES 909#ifdef MANY_CORES
880 abort (); 910 abort ();
881#endif 911#endif
882 } 912 }
883 913
884 if (QUERY_FLAG (ob, FLAG_FRIENDLY)) 914 if (QUERY_FLAG (this, FLAG_FRIENDLY))
885 { 915 {
886 LOG (llevMonster, "Warning: tried to free friendly object.\n"); 916 LOG (llevMonster, "Warning: tried to free friendly object.\n");
887 remove_friendly_object (ob); 917 remove_friendly_object (this);
888 } 918 }
889 919
890 if (QUERY_FLAG (ob, FLAG_FREED)) 920 if (QUERY_FLAG (this, FLAG_FREED))
891 { 921 {
892 dump_object (ob); 922 dump_object (this);
893 LOG (llevError, "Trying to free freed object.\n%s\n", errmsg); 923 LOG (llevError, "Trying to free freed object.\n%s\n", errmsg);
894 return; 924 return;
895 } 925 }
896 926
897 if (ob->more != NULL) 927 if (more)
898 { 928 {
899 free_object2 (ob->more, free_inventory); 929 more->free (free_inventory);
900 ob->more = NULL; 930 more = 0;
901 } 931 }
902 932
903 if (ob->inv) 933 if (inv)
904 { 934 {
905 /* Only if the space blocks everything do we not process - 935 /* Only if the space blocks everything do we not process -
906 * if some form of movement is allowed, let objects 936 * if some form of movement is allowed, let objects
907 * drop on that space. 937 * drop on that space.
908 */ 938 */
909 if (free_inventory || ob->map == NULL 939 if (free_inventory || !map
910 || ob->map->in_memory != MAP_IN_MEMORY 940 || map->in_memory != MAP_IN_MEMORY
911 || (GET_MAP_MOVE_BLOCK (ob->map, ob->x, ob->y) == MOVE_ALL)) 941 || (GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL))
912 { 942 {
913 op = ob->inv; 943 object *op = inv;
914 944
915 while (op != NULL) 945 while (op)
916 { 946 {
917 tmp = op->below; 947 object *tmp = op->below;
918 remove_ob (op); 948 remove_ob (op);
919 free_object2 (op, free_inventory); 949 op->free (free_inventory);
920 op = tmp; 950 op = tmp;
921 } 951 }
922 } 952 }
923 else 953 else
924 { /* Put objects in inventory onto this space */ 954 { /* Put objects in inventory onto this space */
925 op = ob->inv; 955 object *op = inv;
926 956
927 while (op != NULL) 957 while (op)
928 { 958 {
929 tmp = op->below; 959 object *tmp = op->below;
930 remove_ob (op); 960 remove_ob (op);
931 961
932 if (QUERY_FLAG (op, FLAG_STARTEQUIP) 962 if (QUERY_FLAG (op, FLAG_STARTEQUIP)
933 || QUERY_FLAG (op, FLAG_NO_DROP) || op->type == RUNE 963 || QUERY_FLAG (op, FLAG_NO_DROP) || op->type == RUNE
934 || op->type == TRAP || QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) 964 || op->type == TRAP || QUERY_FLAG (op, FLAG_IS_A_TEMPLATE))
935 free_object (op); 965 free_object (op);
936 else 966 else
937 { 967 {
938 op->x = ob->x; 968 op->x = x;
939 op->y = ob->y; 969 op->y = y;
940 insert_ob_in_map (op, ob->map, NULL, 0); /* Insert in same map as the envir */ 970 insert_ob_in_map (op, map, 0, 0); /* Insert in same map as the envir */
941 } 971 }
942 972
943 op = tmp; 973 op = tmp;
944 } 974 }
945 } 975 }
946 } 976 }
947 977
948 /* Remove object from the active list */ 978 /* Remove object from the active list */
949 ob->speed = 0; 979 speed = 0;
950 update_ob_speed (ob); 980 update_ob_speed (this);
951 981
982 unlink ();
983
952 SET_FLAG (ob, FLAG_FREED); 984 SET_FLAG (this, FLAG_FREED);
953 ob->count = 0;
954 985
955 /* Remove this object from the list of used objects */ 986 mortals.push_back (this);
956 if (ob->prev == NULL)
957 {
958 objects = ob->next;
959
960 if (objects != NULL)
961 objects->prev = NULL;
962 }
963 else
964 {
965 ob->prev->next = ob->next;
966
967 if (ob->next != NULL)
968 ob->next->prev = ob->prev;
969 }
970
971 free_key_values (ob);
972
973 /* Now link it with the free_objects list: */
974 ob->prev = 0;
975 ob->next = 0;
976
977 delete ob;
978} 987}
979 988
980/* 989/*
981 * sub_weight() recursively (outwards) subtracts a number from the 990 * sub_weight() recursively (outwards) subtracts a number from the
982 * weight of an object (and what is carried by it's environment(s)). 991 * weight of an object (and what is carried by it's environment(s)).

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines