… | |
… | |
57 | tmp->map = op->map; |
57 | tmp->map = op->map; |
58 | tmp->level = op->level; |
58 | tmp->level = op->level; |
59 | insert_ob_in_map (tmp, op->map, op, 0); |
59 | insert_ob_in_map (tmp, op->map, op, 0); |
60 | } |
60 | } |
61 | |
61 | |
|
|
62 | op->destroy_inv (true); // be explicit about dropping |
62 | op->destroy (); |
63 | op->destroy (true); |
63 | } |
64 | } |
64 | |
65 | |
65 | void |
66 | void |
66 | remove_door2 (object *op) |
67 | remove_door2 (object *op) |
67 | { |
68 | { |
… | |
… | |
86 | tmp->map = op->map; |
87 | tmp->map = op->map; |
87 | tmp->level = op->level; |
88 | tmp->level = op->level; |
88 | insert_ob_in_map (tmp, op->map, op, 0); |
89 | insert_ob_in_map (tmp, op->map, op, 0); |
89 | } |
90 | } |
90 | |
91 | |
|
|
92 | op->destroy_inv (true); // be explicit about dropping |
91 | op->destroy (); |
93 | op->destroy (true); |
92 | } |
94 | } |
93 | |
95 | |
94 | void |
96 | void |
95 | generate_monster (object *gen) |
97 | generate_monster (object *gen) |
96 | { |
98 | { |
… | |
… | |
149 | create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty); |
151 | create_treasure (op->randomitems, op, GT_APPLY, gen->map->difficulty); |
150 | |
152 | |
151 | return; |
153 | return; |
152 | } |
154 | } |
153 | |
155 | |
154 | op->destroy (); |
156 | op->destroy (true); |
155 | } |
157 | } |
156 | |
158 | |
157 | void |
159 | void |
158 | remove_force (object *op) |
160 | remove_force (object *op) |
159 | { |
161 | { |
… | |
… | |
171 | CLEAR_FLAG (op, FLAG_APPLIED); |
173 | CLEAR_FLAG (op, FLAG_APPLIED); |
172 | change_abil (op->env, op); |
174 | change_abil (op->env, op); |
173 | op->env->update_stats (); |
175 | op->env->update_stats (); |
174 | } |
176 | } |
175 | |
177 | |
176 | op->destroy (); |
178 | op->destroy (true); |
177 | } |
179 | } |
178 | |
180 | |
179 | void |
181 | void |
180 | remove_blindness (object *op) |
182 | remove_blindness (object *op) |
181 | { |
183 | { |
… | |
… | |
188 | { |
190 | { |
189 | change_abil (op->env, op); |
191 | change_abil (op->env, op); |
190 | op->env->update_stats (); |
192 | op->env->update_stats (); |
191 | } |
193 | } |
192 | |
194 | |
193 | op->destroy (); |
195 | op->destroy (true); |
194 | } |
196 | } |
195 | |
197 | |
196 | void |
198 | void |
197 | poison_more (object *op) |
199 | poison_more (object *op) |
198 | { |
200 | { |
199 | if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0) |
201 | if (op->env == NULL || !QUERY_FLAG (op->env, FLAG_ALIVE) || op->env->stats.hp < 0) |
200 | { |
202 | { |
201 | op->destroy (); |
203 | op->destroy (true); |
202 | return; |
204 | return; |
203 | } |
205 | } |
204 | |
206 | |
205 | if (op->stats.food == 1) |
207 | if (op->stats.food == 1) |
206 | { |
208 | { |
… | |
… | |
212 | CLEAR_FLAG (op, FLAG_APPLIED); |
214 | CLEAR_FLAG (op, FLAG_APPLIED); |
213 | op->env->update_stats (); |
215 | op->env->update_stats (); |
214 | new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now."); |
216 | new_draw_info (NDI_UNIQUE, 0, op->env, "You feel much better now."); |
215 | } |
217 | } |
216 | |
218 | |
217 | op->destroy (); |
219 | op->destroy (true); |
218 | return; |
220 | return; |
219 | } |
221 | } |
220 | |
222 | |
221 | if (op->env->type == PLAYER) |
223 | if (op->env->type == PLAYER) |
222 | { |
224 | { |
… | |
… | |
631 | if (INVOKE_OBJECT (STOP, op)) |
633 | if (INVOKE_OBJECT (STOP, op)) |
632 | return; |
634 | return; |
633 | |
635 | |
634 | if (op->inv) |
636 | if (op->inv) |
635 | { |
637 | { |
|
|
638 | // replace this by straightforward drop to ground? |
636 | object *payload = op->inv; |
639 | object *payload = op->inv; |
637 | |
640 | |
638 | payload->remove (); |
|
|
639 | payload->owner = 0; |
641 | payload->owner = 0; |
640 | insert_ob_in_map (payload, op->map, payload, 0); |
642 | insert_ob_in_map (payload, op->map, payload, 0); |
641 | op->destroy (); |
643 | op->destroy (true); |
642 | } |
644 | } |
643 | else |
645 | else |
644 | { |
646 | { |
645 | op = fix_stopped_arrow (op); |
647 | op = fix_stopped_arrow (op); |
646 | |
648 | |
… | |
… | |
657 | int was_reflected; |
659 | int was_reflected; |
658 | |
660 | |
659 | if (!op->map) |
661 | if (!op->map) |
660 | { |
662 | { |
661 | LOG (llevError, "BUG: Arrow had no map.\n"); |
663 | LOG (llevError, "BUG: Arrow had no map.\n"); |
662 | op->destroy (); |
664 | op->destroy (true); |
663 | return; |
665 | return; |
664 | } |
666 | } |
665 | |
667 | |
666 | /* we need to stop thrown objects at some point. Like here. */ |
668 | /* we need to stop thrown objects at some point. Like here. */ |
667 | if (op->type == THROWN_OBJ) |
669 | if (op->type == THROWN_OBJ) |
… | |
… | |
672 | * is if the player throws a bomb - the bomb explodes on its own, |
674 | * is if the player throws a bomb - the bomb explodes on its own, |
673 | * but this object sticks around. We could handle the cleanup in the |
675 | * but this object sticks around. We could handle the cleanup in the |
674 | * bomb code, but there are potential other cases where that could happen, |
676 | * bomb code, but there are potential other cases where that could happen, |
675 | * and it is easy enough to clean it up here. |
677 | * and it is easy enough to clean it up here. |
676 | */ |
678 | */ |
677 | if (op->inv == NULL) |
679 | if (!op->inv) |
678 | { |
680 | { |
679 | op->destroy (); |
681 | op->destroy (true); |
680 | return; |
682 | return; |
681 | } |
683 | } |
682 | |
684 | |
683 | if (op->last_sp-- < 0) |
685 | if (op->last_sp-- < 0) |
684 | { |
686 | { |
… | |
… | |
863 | env->insert (tmp); |
865 | env->insert (tmp); |
864 | else |
866 | else |
865 | { |
867 | { |
866 | j = find_first_free_spot (tmp, op->map, op->x, op->y); |
868 | j = find_first_free_spot (tmp, op->map, op->x, op->y); |
867 | if (j < 0) /* No free spot */ |
869 | if (j < 0) /* No free spot */ |
868 | tmp->destroy (); |
870 | tmp->destroy (true); |
869 | else |
871 | else |
870 | { |
872 | { |
871 | mapxy pos (op); pos.move (j); |
873 | mapxy pos (op); pos.move (j); |
872 | |
874 | |
873 | if (pos.normalise ()) |
875 | if (pos.normalise ()) |
874 | pos.insert (tmp, op); |
876 | pos.insert (tmp, op); |
875 | } |
877 | } |
876 | } |
878 | } |
877 | } |
879 | } |
878 | |
880 | |
879 | op->destroy (); |
881 | op->destroy (true); |
880 | } |
882 | } |
881 | |
883 | |
882 | void |
884 | void |
883 | move_teleporter (object *op) |
885 | move_teleporter (object *op) |
884 | { |
886 | { |
… | |
… | |
921 | else if (EXIT_X (head) || EXIT_Y (head)) |
923 | else if (EXIT_X (head) || EXIT_Y (head)) |
922 | { |
924 | { |
923 | if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head))) |
925 | if (out_of_map (head->map, EXIT_X (head), EXIT_Y (head))) |
924 | { |
926 | { |
925 | LOG (llevError, "Removed illegal teleporter.\n"); |
927 | LOG (llevError, "Removed illegal teleporter.\n"); |
926 | head->destroy (); |
928 | head->destroy (true); |
927 | return; |
929 | return; |
928 | } |
930 | } |
929 | |
931 | |
930 | if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp))) |
932 | if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp))) |
931 | return; |
933 | return; |
… | |
… | |
1125 | for (tmp = op->above; tmp; tmp = tmp->above) |
1127 | for (tmp = op->above; tmp; tmp = tmp->above) |
1126 | { |
1128 | { |
1127 | if (op->other_arch->archname == tmp->arch->archname) |
1129 | if (op->other_arch->archname == tmp->arch->archname) |
1128 | { |
1130 | { |
1129 | if (op->level <= 0) |
1131 | if (op->level <= 0) |
1130 | tmp->destroy (); |
1132 | tmp->destroy (true); |
1131 | else |
1133 | else |
1132 | { |
1134 | { |
1133 | uint64 new_nrof = (uint64) tmp->nrof * op->level; |
1135 | uint64 new_nrof = (uint64) tmp->nrof * op->level; |
1134 | |
1136 | |
1135 | if (new_nrof >= 1UL << 31) |
1137 | if (new_nrof >= 1UL << 31) |
… | |
… | |
1200 | } |
1202 | } |
1201 | |
1203 | |
1202 | /* Make sure this multipart object fits */ |
1204 | /* Make sure this multipart object fits */ |
1203 | if (new_ob->arch->more && new_ob->blocked (creator->map, creator->x, creator->y)) |
1205 | if (new_ob->arch->more && new_ob->blocked (creator->map, creator->x, creator->y)) |
1204 | { |
1206 | { |
|
|
1207 | op->destroy_inv (false); // remove when desttroy does this |
1205 | new_ob->destroy (); |
1208 | new_ob->destroy (true); |
1206 | return; |
1209 | return; |
1207 | } |
1210 | } |
1208 | |
1211 | |
1209 | // for now lets try to identify everything generated here, it mostly |
1212 | // for now lets try to identify everything generated here, it mostly |
1210 | // happens automated, so this will at least fix many identify-experience holes |
1213 | // happens automated, so this will at least fix many identify-experience holes |
… | |
… | |
1213 | insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y); |
1216 | insert_ob_in_map_at (new_ob, creator->map, creator, 0, creator->x, creator->y); |
1214 | if (QUERY_FLAG (new_ob, FLAG_FREED)) |
1217 | if (QUERY_FLAG (new_ob, FLAG_FREED)) |
1215 | return; |
1218 | return; |
1216 | |
1219 | |
1217 | if (creator->slaying) |
1220 | if (creator->slaying) |
1218 | { |
|
|
1219 | new_ob->name = new_ob->title = creator->slaying; |
1221 | new_ob->name = new_ob->title = creator->slaying; |
1220 | } |
|
|
1221 | } |
1222 | } |
1222 | |
1223 | |
1223 | /* move_marker --peterm@soda.csua.berkeley.edu |
1224 | /* move_marker --peterm@soda.csua.berkeley.edu |
1224 | when moved, a marker will search for a player sitting above |
1225 | when moved, a marker will search for a player sitting above |
1225 | it, and insert an invisible, weightless force into him |
1226 | it, and insert an invisible, weightless force into him |
… | |
… | |
1233 | { |
1234 | { |
1234 | if (object *tmp = op->ms ().player ()) |
1235 | if (object *tmp = op->ms ().player ()) |
1235 | { |
1236 | { |
1236 | /* remove an old force with a slaying field == op->name */ |
1237 | /* remove an old force with a slaying field == op->name */ |
1237 | if (object *force = tmp->force_find (op->name)) |
1238 | if (object *force = tmp->force_find (op->name)) |
1238 | force->destroy (); |
1239 | force->destroy (true); |
1239 | |
1240 | |
1240 | if (!tmp->force_find (op->slaying)) |
1241 | if (!tmp->force_find (op->slaying)) |
1241 | { |
1242 | { |
1242 | tmp->force_add (op->slaying, op->stats.food); |
1243 | tmp->force_add (op->slaying, op->stats.food); |
1243 | |
1244 | |
… | |
… | |
1249 | op->stats.hp--; |
1250 | op->stats.hp--; |
1250 | |
1251 | |
1251 | if (op->stats.hp == 0) |
1252 | if (op->stats.hp == 0) |
1252 | { |
1253 | { |
1253 | /* marker expires--granted mark number limit */ |
1254 | /* marker expires--granted mark number limit */ |
1254 | op->destroy (); |
1255 | op->destroy (true); |
1255 | return; |
1256 | return; |
1256 | } |
1257 | } |
1257 | } |
1258 | } |
1258 | } |
1259 | } |
1259 | } |
1260 | } |
… | |
… | |
1299 | { |
1300 | { |
1300 | if (QUERY_FLAG (op, FLAG_APPLIED)) |
1301 | if (QUERY_FLAG (op, FLAG_APPLIED)) |
1301 | remove_force (op); |
1302 | remove_force (op); |
1302 | else |
1303 | else |
1303 | { |
1304 | { |
1304 | op->remove (); |
1305 | op->remove (); // TODO: really necessary? |
1305 | |
1306 | |
1306 | if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) |
1307 | if (QUERY_FLAG (op, FLAG_SEE_ANYWHERE)) |
1307 | make_sure_not_seen (op); |
1308 | make_sure_not_seen (op); |
1308 | |
1309 | |
|
|
1310 | op->destroy_inv (false); // be explicit about dropping |
1309 | op->destroy (); |
1311 | op->destroy (true); |
1310 | } |
1312 | } |
1311 | |
1313 | |
1312 | return; |
1314 | return; |
1313 | } |
1315 | } |
1314 | } |
1316 | } |