… | |
… | |
778 | |
778 | |
779 | prev = 0; |
779 | prev = 0; |
780 | next = 0; |
780 | next = 0; |
781 | } |
781 | } |
782 | |
782 | |
783 | object *object::create () |
|
|
784 | { |
|
|
785 | object *op = new object; |
|
|
786 | op->link (); |
|
|
787 | return op; |
|
|
788 | } |
|
|
789 | |
|
|
790 | void |
|
|
791 | object::do_destroy () |
|
|
792 | { |
|
|
793 | attachable::do_destroy (); |
|
|
794 | |
|
|
795 | if (flag [FLAG_IS_LINKED]) |
|
|
796 | remove_button_link (this); |
|
|
797 | |
|
|
798 | if (flag [FLAG_FRIENDLY]) |
|
|
799 | remove_friendly_object (this); |
|
|
800 | |
|
|
801 | if (!flag [FLAG_REMOVED]) |
|
|
802 | remove (); |
|
|
803 | |
|
|
804 | if (flag [FLAG_FREED]) |
|
|
805 | return; |
|
|
806 | |
|
|
807 | flag [FLAG_FREED] = 1; |
|
|
808 | |
|
|
809 | while (inv) |
|
|
810 | inv->destroy (); |
|
|
811 | |
|
|
812 | set_speed (0); |
|
|
813 | unlink (); |
|
|
814 | |
|
|
815 | // hack to ensure that freed objects still have a valid map |
|
|
816 | { |
|
|
817 | static maptile *freed_map; // freed objects are moved here to avoid crashes |
|
|
818 | |
|
|
819 | if (!freed_map) |
|
|
820 | { |
|
|
821 | freed_map = new maptile; |
|
|
822 | |
|
|
823 | freed_map->name = "/internal/freed_objects_map"; |
|
|
824 | freed_map->width = 3; |
|
|
825 | freed_map->height = 3; |
|
|
826 | |
|
|
827 | freed_map->allocate (); |
|
|
828 | } |
|
|
829 | |
|
|
830 | map = freed_map; |
|
|
831 | x = 1; |
|
|
832 | y = 1; |
|
|
833 | } |
|
|
834 | |
|
|
835 | head = 0; |
|
|
836 | |
|
|
837 | if (more) |
|
|
838 | { |
|
|
839 | more->destroy (); |
|
|
840 | more = 0; |
|
|
841 | } |
|
|
842 | |
|
|
843 | // clear those pointers that likely might have circular references to us |
|
|
844 | owner = 0; |
|
|
845 | enemy = 0; |
|
|
846 | attacked_by = 0; |
|
|
847 | |
|
|
848 | // only relevant for players(?), but make sure of it anyways |
|
|
849 | contr = 0; |
|
|
850 | } |
|
|
851 | |
|
|
852 | /* |
783 | /* |
853 | * Remove and free all objects in the inventory of the given object. |
784 | * Remove and free all objects in the inventory of the given object. |
854 | * object.c ? |
785 | * object.c ? |
855 | */ |
786 | */ |
856 | void |
787 | void |
… | |
… | |
858 | { |
789 | { |
859 | /* Only if the space blocks everything do we not process - |
790 | /* Only if the space blocks everything do we not process - |
860 | * if some form of movement is allowed, let objects |
791 | * if some form of movement is allowed, let objects |
861 | * drop on that space. |
792 | * drop on that space. |
862 | */ |
793 | */ |
863 | if (!drop_to_ground || !map || map->in_memory != MAP_IN_MEMORY || GET_MAP_MOVE_BLOCK (map, x, y) == MOVE_ALL) |
794 | if (!drop_to_ground |
|
|
795 | || !map |
|
|
796 | || map->in_memory != MAP_IN_MEMORY |
|
|
797 | || map->at (x, y).move_block == MOVE_ALL) |
864 | { |
798 | { |
865 | while (inv) |
799 | while (inv) |
|
|
800 | { |
|
|
801 | inv->destroy_inv (drop_to_ground); |
866 | inv->destroy (); |
802 | inv->destroy (); |
|
|
803 | } |
867 | } |
804 | } |
868 | else |
805 | else |
869 | { /* Put objects in inventory onto this space */ |
806 | { /* Put objects in inventory onto this space */ |
870 | while (inv) |
807 | while (inv) |
871 | { |
808 | { |
… | |
… | |
876 | || op->type == RUNE |
813 | || op->type == RUNE |
877 | || op->type == TRAP |
814 | || op->type == TRAP |
878 | || op->flag [FLAG_IS_A_TEMPLATE]) |
815 | || op->flag [FLAG_IS_A_TEMPLATE]) |
879 | op->destroy (); |
816 | op->destroy (); |
880 | else |
817 | else |
881 | { |
818 | map->insert (op, x, y); |
882 | op->remove (); |
|
|
883 | op->x = x; |
|
|
884 | op->y = y; |
|
|
885 | insert_ob_in_map (op, map, 0, 0); /* Insert in same map as the envir */ |
|
|
886 | } |
|
|
887 | } |
819 | } |
888 | } |
820 | } |
|
|
821 | } |
|
|
822 | |
|
|
823 | object *object::create () |
|
|
824 | { |
|
|
825 | object *op = new object; |
|
|
826 | op->link (); |
|
|
827 | return op; |
|
|
828 | } |
|
|
829 | |
|
|
830 | void |
|
|
831 | object::do_destroy () |
|
|
832 | { |
|
|
833 | if (flag [FLAG_IS_LINKED]) |
|
|
834 | remove_button_link (this); |
|
|
835 | |
|
|
836 | if (flag [FLAG_FRIENDLY]) |
|
|
837 | remove_friendly_object (this); |
|
|
838 | |
|
|
839 | if (!flag [FLAG_REMOVED]) |
|
|
840 | remove (); |
|
|
841 | |
|
|
842 | if (flag [FLAG_FREED]) |
|
|
843 | return; |
|
|
844 | |
|
|
845 | set_speed (0); |
|
|
846 | |
|
|
847 | flag [FLAG_FREED] = 1; |
|
|
848 | |
|
|
849 | attachable::do_destroy (); |
|
|
850 | |
|
|
851 | destroy_inv (true); |
|
|
852 | unlink (); |
|
|
853 | |
|
|
854 | // hack to ensure that freed objects still have a valid map |
|
|
855 | { |
|
|
856 | static maptile *freed_map; // freed objects are moved here to avoid crashes |
|
|
857 | |
|
|
858 | if (!freed_map) |
|
|
859 | { |
|
|
860 | freed_map = new maptile; |
|
|
861 | |
|
|
862 | freed_map->name = "/internal/freed_objects_map"; |
|
|
863 | freed_map->width = 3; |
|
|
864 | freed_map->height = 3; |
|
|
865 | |
|
|
866 | freed_map->allocate (); |
|
|
867 | } |
|
|
868 | |
|
|
869 | map = freed_map; |
|
|
870 | x = 1; |
|
|
871 | y = 1; |
|
|
872 | } |
|
|
873 | |
|
|
874 | head = 0; |
|
|
875 | |
|
|
876 | if (more) |
|
|
877 | { |
|
|
878 | more->destroy (); |
|
|
879 | more = 0; |
|
|
880 | } |
|
|
881 | |
|
|
882 | // clear those pointers that likely might have circular references to us |
|
|
883 | owner = 0; |
|
|
884 | enemy = 0; |
|
|
885 | attacked_by = 0; |
|
|
886 | |
|
|
887 | // only relevant for players(?), but make sure of it anyways |
|
|
888 | contr = 0; |
889 | } |
889 | } |
890 | |
890 | |
891 | void |
891 | void |
892 | object::destroy (bool destroy_inventory) |
892 | object::destroy (bool destroy_inventory) |
893 | { |
893 | { |
894 | if (destroyed ()) |
894 | if (destroyed ()) |
895 | return; |
895 | return; |
896 | |
896 | |
897 | if (destroy_inventory) |
897 | if (destroy_inventory) |
898 | destroy_inv (true); |
898 | destroy_inv (false); |
899 | |
899 | |
900 | attachable::destroy (); |
900 | attachable::destroy (); |
901 | } |
901 | } |
902 | |
902 | |
903 | /* |
903 | /* |
… | |
… | |
1016 | if (map->in_memory == MAP_SAVING) |
1016 | if (map->in_memory == MAP_SAVING) |
1017 | return; |
1017 | return; |
1018 | |
1018 | |
1019 | int check_walk_off = !flag [FLAG_NO_APPLY]; |
1019 | int check_walk_off = !flag [FLAG_NO_APPLY]; |
1020 | |
1020 | |
1021 | for (tmp = GET_MAP_OB (map, x, y); tmp; tmp = tmp->above) |
1021 | for (tmp = map->at (x, y).bot; tmp; tmp = tmp->above) |
1022 | { |
1022 | { |
1023 | /* No point updating the players look faces if he is the object |
1023 | /* No point updating the players look faces if he is the object |
1024 | * being removed. |
1024 | * being removed. |
1025 | */ |
1025 | */ |
1026 | |
1026 | |
… | |
… | |
1112 | * job preparing multi-part monsters |
1112 | * job preparing multi-part monsters |
1113 | */ |
1113 | */ |
1114 | object * |
1114 | object * |
1115 | insert_ob_in_map_at (object *op, maptile *m, object *originator, int flag, int x, int y) |
1115 | insert_ob_in_map_at (object *op, maptile *m, object *originator, int flag, int x, int y) |
1116 | { |
1116 | { |
1117 | object *tmp; |
|
|
1118 | |
|
|
1119 | if (op->head) |
|
|
1120 | op = op->head; |
|
|
1121 | |
|
|
1122 | for (tmp = op; tmp; tmp = tmp->more) |
1117 | for (object *tmp = op->head_ (); tmp; tmp = tmp->more) |
1123 | { |
1118 | { |
1124 | tmp->x = x + tmp->arch->clone.x; |
1119 | tmp->x = x + tmp->arch->clone.x; |
1125 | tmp->y = y + tmp->arch->clone.y; |
1120 | tmp->y = y + tmp->arch->clone.y; |
1126 | } |
1121 | } |
1127 | |
1122 | |
… | |
… | |
1441 | tmp1->x = op->x; |
1436 | tmp1->x = op->x; |
1442 | tmp1->y = op->y; |
1437 | tmp1->y = op->y; |
1443 | insert_ob_in_map (tmp1, op->map, op, 0); |
1438 | insert_ob_in_map (tmp1, op->map, op, 0); |
1444 | } |
1439 | } |
1445 | |
1440 | |
|
|
1441 | object * |
|
|
1442 | object::insert_at (object *where, object *originator, int flags) |
|
|
1443 | { |
|
|
1444 | where->map->insert (this, where->x, where->y, originator, flags); |
|
|
1445 | } |
|
|
1446 | |
1446 | /* |
1447 | /* |
1447 | * get_split_ob(ob,nr) splits up ob into two parts. The part which |
1448 | * get_split_ob(ob,nr) splits up ob into two parts. The part which |
1448 | * is returned contains nr objects, and the remaining parts contains |
1449 | * is returned contains nr objects, and the remaining parts contains |
1449 | * the rest (or is removed and freed if that number is 0). |
1450 | * the rest (or is removed and freed if that number is 0). |
1450 | * On failure, NULL is returned, and the reason put into the |
1451 | * On failure, NULL is returned, and the reason put into the |
1451 | * global static errmsg array. |
1452 | * global static errmsg array. |
1452 | */ |
1453 | */ |
1453 | |
|
|
1454 | object * |
1454 | object * |
1455 | get_split_ob (object *orig_ob, uint32 nr) |
1455 | get_split_ob (object *orig_ob, uint32 nr) |
1456 | { |
1456 | { |
1457 | object *newob; |
1457 | object *newob; |
1458 | int is_removed = (QUERY_FLAG (orig_ob, FLAG_REMOVED) != 0); |
1458 | int is_removed = (QUERY_FLAG (orig_ob, FLAG_REMOVED) != 0); |
… | |
… | |
1722 | * |
1722 | * |
1723 | * MSW 2001-07-08: Check all objects on space, not just those below |
1723 | * MSW 2001-07-08: Check all objects on space, not just those below |
1724 | * object being inserted. insert_ob_in_map may not put new objects |
1724 | * object being inserted. insert_ob_in_map may not put new objects |
1725 | * on top. |
1725 | * on top. |
1726 | */ |
1726 | */ |
1727 | |
|
|
1728 | int |
1727 | int |
1729 | check_move_on (object *op, object *originator) |
1728 | check_move_on (object *op, object *originator) |
1730 | { |
1729 | { |
1731 | object *tmp; |
1730 | object *tmp; |
1732 | maptile *m = op->map; |
1731 | maptile *m = op->map; |