… | |
… | |
273 | */ |
273 | */ |
274 | |
274 | |
275 | int |
275 | int |
276 | hit_map (object *op, int dir, int type, int full_hit) |
276 | hit_map (object *op, int dir, int type, int full_hit) |
277 | { |
277 | { |
278 | object *tmp, *next; |
|
|
279 | maptile *map; |
278 | maptile *map; |
280 | sint16 x, y; |
279 | sint16 x, y; |
281 | int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ |
280 | int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ |
282 | |
281 | |
283 | if (QUERY_FLAG (op, FLAG_FREED)) |
282 | if (QUERY_FLAG (op, FLAG_FREED)) |
… | |
… | |
334 | shuffle_attack (op, 1); /*1 flag tells it to change the face */ |
333 | shuffle_attack (op, 1); /*1 flag tells it to change the face */ |
335 | update_object (op, UP_OBJ_FACE); |
334 | update_object (op, UP_OBJ_FACE); |
336 | type &= ~AT_CHAOS; |
335 | type &= ~AT_CHAOS; |
337 | } |
336 | } |
338 | |
337 | |
339 | next = GET_MAP_OB (map, x, y); |
|
|
340 | |
|
|
341 | while (next) |
|
|
342 | { |
|
|
343 | if (next->destroyed ()) |
|
|
344 | { |
|
|
345 | /* There may still be objects that were above 'next', but there is no |
338 | /* There may still be objects that were above 'next', but there is no |
346 | * simple way to find out short of copying all object references and |
339 | * simple way to find out short of copying all object references and |
347 | * tags into a temporary array before we start processing the first |
340 | * tags into a temporary array before we start processing the first |
348 | * object. That's why we just abort. |
341 | * object. That's why we just abort on destroy. |
349 | * |
342 | * |
350 | * This happens whenever attack spells (like fire) hit a pile |
343 | * This happens whenever attack spells (like fire) hit a pile |
351 | * of objects. This is not a bug - nor an error. The errormessage |
344 | * of objects. This is not a bug - nor an error. |
352 | * below was spamming the logs for absolutely no reason. |
345 | */ |
353 | */ |
346 | for (object *next = map->at (x, y).bot; next && !next->destroyed (); ) |
354 | /* LOG (llevDebug, "hit_map(): next object destroyed\n"); */ |
347 | { |
355 | break; |
|
|
356 | } |
|
|
357 | |
|
|
358 | tmp = next; |
348 | object *tmp = next; |
359 | next = tmp->above; |
349 | next = tmp->above; |
360 | |
|
|
361 | if (tmp->destroyed ()) |
|
|
362 | { |
|
|
363 | LOG (llevError, "BUG: hit_map(): found freed object\n"); |
|
|
364 | break; |
|
|
365 | } |
|
|
366 | |
350 | |
367 | /* Something could have happened to 'tmp' while 'tmp->below' was processed. |
351 | /* Something could have happened to 'tmp' while 'tmp->below' was processed. |
368 | * For example, 'tmp' was put in an icecube. |
352 | * For example, 'tmp' was put in an icecube. |
369 | * This is one of the few cases where on_same_map should not be used. |
353 | * This is one of the few cases where on_same_map should not be used. |
370 | */ |
354 | */ |
… | |
… | |
376 | hit_player (tmp, op->stats.dam, op, type, full_hit); |
360 | hit_player (tmp, op->stats.dam, op, type, full_hit); |
377 | retflag |= 1; |
361 | retflag |= 1; |
378 | if (op->destroyed ()) |
362 | if (op->destroyed ()) |
379 | break; |
363 | break; |
380 | } |
364 | } |
381 | |
|
|
382 | /* Here we are potentially destroying an object. If the object has |
365 | /* Here we are potentially destroying an object. If the object has |
383 | * NO_PASS set, it is also immune - you can't destroy walls. Note |
366 | * NO_PASS set, it is also immune - you can't destroy walls. Note |
384 | * that weak walls have is_alive set, which prevent objects from |
367 | * that weak walls have is_alive set, which prevent objects from |
385 | * passing over/through them. We don't care what type of movement |
368 | * passing over/through them. We don't care what type of movement |
386 | * the wall blocks - if it blocks any type of movement, can't be |
369 | * the wall blocks - if it blocks any type of movement, can't be |
387 | * destroyed right now. |
370 | * destroyed right now. |
388 | */ |
371 | */ |
389 | else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block) |
372 | else if ((tmp->material || tmp->materialname) && op->stats.dam > 0 && !tmp->move_block) |
390 | { |
373 | { |
391 | save_throw_object (tmp, type, op); |
374 | save_throw_object (tmp, type, op); |
|
|
375 | |
392 | if (op->destroyed ()) |
376 | if (op->destroyed ()) |
393 | break; |
377 | break; |
394 | } |
378 | } |
395 | } |
379 | } |
396 | |
380 | |