1 | /* |
1 | /* |
2 | * static char *rcsid_object_c = |
2 | * static char *rcsid_object_c = |
3 | * "$Id: object.C,v 1.20 2006/09/08 18:26:22 root Exp $"; |
3 | * "$Id: object.C,v 1.21 2006/09/09 21:48:28 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}; |
56 | int freedir[SIZEOFFREE]= { |
56 | int 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. */ |
62 | static int compare_ob_value_lists_one(const object * wants, const object * has) { |
61 | static int compare_ob_value_lists_one(const object * wants, const object * has) { |
63 | key_value * wants_field; |
62 | key_value * wants_field; |
64 | |
63 | |
… | |
… | |
623 | } |
622 | } |
624 | |
623 | |
625 | update_ob_speed (op); |
624 | update_ob_speed (op); |
626 | } |
625 | } |
627 | |
626 | |
628 | object::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 | |
|
|
646 | object::~object () |
|
|
647 | { |
|
|
648 | } |
|
|
649 | |
|
|
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 |
653 | * be called to update the face variable, _and_ how it looks on the map. |
630 | * be called to update the face variable, _and_ how it looks on the map. |
654 | */ |
631 | */ |
… | |
… | |
854 | |
831 | |
855 | if(op->more!=NULL) |
832 | if(op->more!=NULL) |
856 | update_object(op->more, action); |
833 | update_object(op->more, action); |
857 | } |
834 | } |
858 | |
835 | |
|
|
836 | static std::vector<object *> mortals; |
|
|
837 | |
|
|
838 | void 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 | |
|
|
846 | object::object () |
|
|
847 | { |
|
|
848 | count = ++ob_count; |
|
|
849 | |
|
|
850 | prev = 0; |
|
|
851 | next = objects; |
|
|
852 | |
|
|
853 | if (objects) |
|
|
854 | objects->prev = this; |
|
|
855 | |
|
|
856 | objects = this; |
|
|
857 | |
|
|
858 | SET_FLAG (this, FLAG_REMOVED); |
|
|
859 | |
|
|
860 | expmul = 1.0; |
|
|
861 | face = blank_face; |
|
|
862 | attacked_by_count = -1; |
|
|
863 | } |
|
|
864 | |
|
|
865 | object::~object () |
|
|
866 | { |
|
|
867 | } |
|
|
868 | |
|
|
869 | object *object::create () |
|
|
870 | { |
|
|
871 | return new object; |
|
|
872 | } |
859 | |
873 | |
860 | /* |
874 | /* |
861 | * free_object() frees everything allocated by an object, removes |
875 | * free_object() frees everything allocated by an object, removes |
862 | * it from the list of used objects, and puts it on the list of |
876 | * it from the list of used objects, and puts it on the list of |
863 | * free objects. The IS_FREED() flag is set in the object. |
877 | * free objects. The IS_FREED() flag is set in the object. |
… | |
… | |
865 | * this function to succeed. |
879 | * this function to succeed. |
866 | * |
880 | * |
867 | * If free_inventory is set, free inventory as well. Else drop items in |
881 | * If free_inventory is set, free inventory as well. Else drop items in |
868 | * inventory to the ground. |
882 | * inventory to the ground. |
869 | */ |
883 | */ |
870 | |
|
|
871 | void |
884 | void |
872 | free_object (object * ob) |
885 | object::free (bool free_inventory) |
873 | { |
886 | { |
874 | free_object2 (ob, 0); |
|
|
875 | } |
|
|
876 | |
|
|
877 | void |
|
|
878 | free_object2 (object * ob, int free_inventory) |
|
|
879 | { |
|
|
880 | object *tmp, *op; |
|
|
881 | |
|
|
882 | if (!QUERY_FLAG (ob, FLAG_REMOVED)) |
887 | if (!QUERY_FLAG (this, FLAG_REMOVED)) |
883 | { |
888 | { |
884 | LOG (llevDebug, "Free object called with non removed object\n"); |
889 | LOG (llevDebug, "Free object called with non removed object\n"); |
885 | dump_object (ob); |
890 | dump_object (this); |
886 | #ifdef MANY_CORES |
891 | #ifdef MANY_CORES |
887 | abort (); |
892 | abort (); |
888 | #endif |
893 | #endif |
889 | } |
894 | } |
890 | |
895 | |
891 | if (QUERY_FLAG (ob, FLAG_FRIENDLY)) |
896 | if (QUERY_FLAG (this, FLAG_FRIENDLY)) |
892 | { |
897 | { |
893 | LOG (llevMonster, "Warning: tried to free friendly object.\n"); |
898 | LOG (llevMonster, "Warning: tried to free friendly object.\n"); |
894 | remove_friendly_object (ob); |
899 | remove_friendly_object (this); |
895 | } |
900 | } |
896 | |
901 | |
897 | if (QUERY_FLAG (ob, FLAG_FREED)) |
902 | if (QUERY_FLAG (this, FLAG_FREED)) |
898 | { |
903 | { |
899 | dump_object (ob); |
904 | dump_object (this); |
900 | LOG (llevError, "Trying to free freed object.\n%s\n", errmsg); |
905 | LOG (llevError, "Trying to free freed object.\n%s\n", errmsg); |
901 | return; |
906 | return; |
902 | } |
907 | } |
903 | |
908 | |
904 | if (ob->more != NULL) |
909 | if (more) |
905 | { |
910 | { |
906 | free_object2 (ob->more, free_inventory); |
911 | more->free (free_inventory); |
907 | ob->more = NULL; |
912 | more = 0; |
908 | } |
913 | } |
909 | |
914 | |
910 | if (ob->inv) |
915 | if (inv) |
911 | { |
916 | { |
912 | /* Only if the space blocks everything do we not process - |
917 | /* Only if the space blocks everything do we not process - |
913 | * if some form of movement is allowed, let objects |
918 | * if some form of movement is allowed, let objects |
914 | * drop on that space. |
919 | * drop on that space. |
915 | */ |
920 | */ |
916 | if (free_inventory || ob->map == NULL |
921 | if (free_inventory || !map |
917 | || ob->map->in_memory != MAP_IN_MEMORY |
922 | || map->in_memory != MAP_IN_MEMORY |
918 | || (GET_MAP_MOVE_BLOCK (ob->map, ob->x, ob->y) == MOVE_ALL)) |
923 | || (GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL)) |
919 | { |
924 | { |
920 | op = ob->inv; |
925 | object *op = inv; |
921 | |
926 | |
922 | while (op != NULL) |
927 | while (op) |
923 | { |
928 | { |
924 | tmp = op->below; |
929 | object *tmp = op->below; |
925 | remove_ob (op); |
930 | remove_ob (op); |
926 | free_object2 (op, free_inventory); |
931 | op->free (free_inventory); |
927 | op = tmp; |
932 | op = tmp; |
928 | } |
933 | } |
929 | } |
934 | } |
930 | else |
935 | else |
931 | { /* Put objects in inventory onto this space */ |
936 | { /* Put objects in inventory onto this space */ |
932 | op = ob->inv; |
937 | object *op = inv; |
933 | |
938 | |
934 | while (op != NULL) |
939 | while (op) |
935 | { |
940 | { |
936 | tmp = op->below; |
941 | object *tmp = op->below; |
937 | remove_ob (op); |
942 | remove_ob (op); |
938 | |
943 | |
939 | if (QUERY_FLAG (op, FLAG_STARTEQUIP) |
944 | if (QUERY_FLAG (op, FLAG_STARTEQUIP) |
940 | || QUERY_FLAG (op, FLAG_NO_DROP) || op->type == RUNE |
945 | || QUERY_FLAG (op, FLAG_NO_DROP) || op->type == RUNE |
941 | || op->type == TRAP || QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) |
946 | || op->type == TRAP || QUERY_FLAG (op, FLAG_IS_A_TEMPLATE)) |
942 | free_object (op); |
947 | free_object (op); |
943 | else |
948 | else |
944 | { |
949 | { |
945 | op->x = ob->x; |
950 | op->x = x; |
946 | op->y = ob->y; |
951 | op->y = y; |
947 | insert_ob_in_map (op, ob->map, NULL, 0); /* Insert in same map as the envir */ |
952 | insert_ob_in_map (op, map, 0, 0); /* Insert in same map as the envir */ |
948 | } |
953 | } |
949 | |
954 | |
950 | op = tmp; |
955 | op = tmp; |
951 | } |
956 | } |
952 | } |
957 | } |
953 | } |
958 | } |
954 | |
959 | |
955 | /* Remove object from the active list */ |
960 | /* Remove object from the active list */ |
956 | ob->speed = 0; |
961 | speed = 0; |
957 | update_ob_speed (ob); |
962 | update_ob_speed (this); |
958 | |
963 | |
959 | SET_FLAG (ob, FLAG_FREED); |
964 | SET_FLAG (this, FLAG_FREED); |
|
|
965 | |
|
|
966 | mortalise (); |
|
|
967 | } |
|
|
968 | |
|
|
969 | void |
|
|
970 | object::mortalise () |
|
|
971 | { |
960 | ob->count = 0; |
972 | count = 0; |
961 | |
973 | |
962 | /* Remove this object from the list of used objects */ |
974 | /* Remove this object from the list of used objects */ |
963 | if (ob->prev == NULL) |
975 | if (prev) prev->next = next; |
964 | { |
976 | if (next) next->prev = prev; |
965 | objects = ob->next; |
977 | if (this == objects) objects = next; |
966 | |
978 | |
967 | if (objects != NULL) |
|
|
968 | objects->prev = NULL; |
|
|
969 | } |
|
|
970 | else |
|
|
971 | { |
|
|
972 | ob->prev->next = ob->next; |
|
|
973 | |
|
|
974 | if (ob->next != NULL) |
|
|
975 | ob->next->prev = ob->prev; |
|
|
976 | } |
|
|
977 | |
|
|
978 | free_key_values (ob); |
979 | free_key_values (this); |
979 | |
980 | |
980 | /* Now link it with the free_objects list: */ |
981 | mortals.push_back (this); |
981 | ob->prev = 0; |
|
|
982 | ob->next = 0; |
|
|
983 | |
|
|
984 | delete ob; |
|
|
985 | } |
982 | } |
986 | |
983 | |
987 | /* |
984 | /* |
988 | * sub_weight() recursively (outwards) subtracts a number from the |
985 | * sub_weight() recursively (outwards) subtracts a number from the |
989 | * weight of an object (and what is carried by it's environment(s)). |
986 | * weight of an object (and what is carried by it's environment(s)). |