summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mstuff2.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/mstuff2.cc')
-rw-r--r--crawl-ref/source/mstuff2.cc36
1 files changed, 35 insertions, 1 deletions
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index f8a5140bf5..487db44742 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -1085,7 +1085,8 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used)
// XXX: ugly hack, but avoids adding dynamic allocation to this code
char throw_buff[ ITEMNAME_SIZE ];
- bool returning = (get_weapon_brand(mitm[hand_used]) == SPWPN_RETURNING);
+ bool returning = (get_weapon_brand(mitm[hand_used]) == SPWPN_RETURNING ||
+ get_ammo_brand(mitm[hand_used]) == SPMSL_RETURNING);
int baseHit = 0, baseDam = 0; // from thrown or ammo
int ammoHitBonus = 0, ammoDamBonus = 0; // from thrown or ammo
@@ -1418,6 +1419,14 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used)
fire_beam( pbolt, really_returns ? NULL : &item );
+ // The item can be destroyed before returning.
+ if (really_returns && mons_thrown_object_destroyed(&item, pbolt.target_x,
+ pbolt.target_y, true,
+ pbolt.beam_source))
+ {
+ really_returns = false;
+ }
+
if ( really_returns )
{
// Fire beam in reverse
@@ -1441,6 +1450,31 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used)
return (true);
} // end mons_throw()
+bool mons_thrown_object_destroyed( item_def *item, int x, int y,
+ bool returning, int midx )
+{
+ ASSERT( item != NULL );
+
+ bool destroyed = ((item->base_type != OBJ_MISSILES ||
+ item->sub_type != MI_THROWING_NET) && coinflip());
+ bool hostile_grid = grid_destroys_items(grd[x][y]);
+
+ // Non-returning items thrown into item-destroying grids are always
+ // destroyed. Returning items are only destroyed if they would have
+ // been randomly destroyed anyway.
+ if (returning && !destroyed)
+ hostile_grid = false;
+
+ if (hostile_grid)
+ {
+ // No destruction sound here. Too much message spam otherwise.
+ item_was_destroyed(*item, midx);
+ destroyed = true;
+ }
+
+ return destroyed;
+}
+
// should really do something about mons_hit, but can't be bothered
void spore_goes_pop(struct monsters *monster)
{