diff options
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/source/beam.cc | 68 | ||||
-rw-r--r-- | crawl-ref/source/describe.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 66 | ||||
-rw-r--r-- | crawl-ref/source/item_use.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/itemname.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/itemprop.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.cc | 36 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.h | 3 |
8 files changed, 129 insertions, 56 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 4e91ca5dfa..9ea7595ec6 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -39,6 +39,7 @@ #include "delay.h" #include "effects.h" #include "enum.h" +#include "item_use.h" #include "it_use2.h" #include "items.h" #include "itemname.h" @@ -2433,62 +2434,25 @@ void beam_drop_object( bolt &beam, item_def *item, int x, int y ) if (beam.is_tracer || beam.flavour != BEAM_MISSILE) return; - if ( grid_destroys_items(grd[x][y]) ) + if ((YOU_KILL(beam.thrower) && + !thrown_object_destroyed(item, x, y, false)) || + (MON_KILL(beam.thrower) && + !mons_thrown_object_destroyed(item, x, y, false, + beam.beam_source))) { - // Too much message spam otherwise - if ( YOU_KILL(beam.thrower) && player_can_hear(x, y) ) - mprf(MSGCH_SOUND, grid_item_destruction_message(grd[x][y])); - - item_was_destroyed(*item, beam.beam_source); - return; - } - - // doesn't get destroyed by throwing - if (item->sub_type == MI_THROWING_NET) - { - // player or monster on position is caught in net - if (you.x_pos == x && you.y_pos == y && you.attribute[ATTR_HELD] - || mgrd[x][y] != NON_MONSTER && mons_is_caught(&menv[mgrd[x][y]])) + if (item->sub_type == MI_THROWING_NET) { - // if no trapping net found mark this one - if (get_trapping_net(x,y, true) == NON_ITEM) - set_item_stationary(*item); - } - - copy_item_to_grid( *item, x, y, 1 ); - return; - } - - if (YOU_KILL(beam.thrower)) // you threw it - { - int chance; - - // [dshaligram] Removed influence of Throwing on ammo preservation. - // The effect is nigh impossible to perceive. - switch (item->sub_type) - { - case MI_NEEDLE: - chance = (get_ammo_brand(*item) == SPMSL_CURARE? 3 : 6); - break; - case MI_SLING_BULLET: - case MI_STONE: chance = 4; break; - case MI_DART: chance = 3; break; - case MI_ARROW: chance = 4; break; - case MI_BOLT: chance = 4; break; - case MI_JAVELIN: chance = 10; break; - - case MI_LARGE_ROCK: - default: - chance = 25; - break; + // player or monster on position is caught in net + if (you.x_pos == x && you.y_pos == y && you.attribute[ATTR_HELD] + || mgrd[x][y] != NON_MONSTER && + mons_is_caught(&menv[mgrd[x][y]])) + { + // if no trapping net found mark this one + if (get_trapping_net(x,y, true) == NON_ITEM) + set_item_stationary(*item); + } } - if (item->base_type != OBJ_MISSILES || !one_chance_in(chance)) - copy_item_to_grid( *item, x, y, 1 ); - } - else if (MON_KILL(beam.thrower) - && (item->base_type != OBJ_MISSILES || coinflip())) - { copy_item_to_grid( *item, x, y, 1 ); } } diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 252d04042b..2013187ce3 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -1399,6 +1399,10 @@ static std::string describe_ammo( const item_def &item ) case SPMSL_CURARE: description += "$It is tipped with asphyxiating poison. "; break; + case SPMSL_RETURNING: + description += "$A skilled user can throw it in such a way " + "that it will return to its owner. "; + break; } } diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 3e62c8f41f..6abc5a71ea 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -2068,8 +2068,10 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, // CALCULATIONS FOR THROWN WEAPONS if (projected == LRET_THROWN) { - returning = (get_weapon_brand(item) == SPWPN_RETURNING && !teleport && - !one_chance_in(1 + skill_bump(SK_THROWING))); + returning = ((get_weapon_brand(item) == SPWPN_RETURNING || + get_ammo_brand(item) == SPMSL_RETURNING) && + !teleport && + !one_chance_in(1 + skill_bump(SK_THROWING))); baseHit = 0; // missiles only use inv_plus @@ -2348,6 +2350,13 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, { // Dropping item copy, since the launched item might be different. fire_beam(pbolt, returning ? NULL : &item); + + // The item can be destroyed before returning. + if (returning && thrown_object_destroyed(&item, pbolt.target_x, + pbolt.target_y, true)) + { + returning = false; + } } if ( returning ) @@ -2379,6 +2388,59 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, return (hit); } // end throw_it() +bool thrown_object_destroyed( item_def *item, int x, int y, bool returning ) +{ + ASSERT( item != NULL ); + + int chance = 0; + bool destroyed = false; + bool hostile_grid = false; + + if (item->base_type == OBJ_MISSILES) + { + // [dshaligram] Removed influence of Throwing on ammo preservation. + // The effect is nigh impossible to perceive. + switch (item->sub_type) + { + case MI_NEEDLE: + chance = (get_ammo_brand(*item) == SPMSL_CURARE ? 3 : 6); + break; + case MI_SLING_BULLET: + case MI_STONE: chance = 4; break; + case MI_DART: chance = 3; break; + case MI_ARROW: chance = 4; break; + case MI_BOLT: chance = 4; break; + case MI_JAVELIN: chance = 10; break; + case MI_THROWING_NET: break; // doesn't get destroyed by throwing + + case MI_LARGE_ROCK: + default: + chance = 25; + break; + } + } + + destroyed = (chance == 0) ? false : one_chance_in(chance); + 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) + { + if (player_can_hear(x, y)) + mprf(MSGCH_SOUND, grid_item_destruction_message(grd[x][y])); + + item_was_destroyed(*item, NON_MONSTER); + destroyed = true; + } + + return destroyed; +} + void jewellery_wear_effects(item_def &item) { item_type_id_state_type ident = ID_TRIED_TYPE; diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h index f38953bb12..e191c6833d 100644 --- a/crawl-ref/source/item_use.h +++ b/crawl-ref/source/item_use.h @@ -170,6 +170,8 @@ bool enchant_weapon( enchant_stat_type which_stat, bool quiet = false ); bool throw_it(bolt &pbolt, int throw_2, bool teleport=false, int acc_bonus=0, dist *target = NULL); +bool thrown_object_destroyed( item_def *item, int x, int y, bool returning ); + void inscribe_item(); int launcher_shield_slowdown(const item_def &launcher, const item_def *shield); diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index cbcee48703..394a1c7160 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -1118,6 +1118,9 @@ std::string item_def::name_aux( description_level_type desc, case SPMSL_POISONED: case SPMSL_CURARE: break; + case SPMSL_RETURNING: + buff << ((terse) ? " (return)" : " of returning"); + break; default: buff << " (buggy)"; } diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h index 6616236128..4c5763afe9 100644 --- a/crawl-ref/source/itemprop.h +++ b/crawl-ref/source/itemprop.h @@ -354,7 +354,8 @@ enum special_missile_type // to separate from weapons in general {dlb} SPMSL_ICE, // 2 SPMSL_POISONED, // 3 SPMSL_POISONED_II, // 4 - unused - SPMSL_CURARE // 5 + SPMSL_CURARE, // 5 + SPMSL_RETURNING // 6 }; enum special_ring_type // jewellery mitm[].special values 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) { diff --git a/crawl-ref/source/mstuff2.h b/crawl-ref/source/mstuff2.h index 25cc10a3bf..ac2877a041 100644 --- a/crawl-ref/source/mstuff2.h +++ b/crawl-ref/source/mstuff2.h @@ -65,6 +65,9 @@ void setup_mons_cast(const monsters *monster, bolt &pbolt, int spell_cast); * *********************************************************************** */ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used); +bool mons_thrown_object_destroyed( item_def *item, int x, int y, + bool returning, int midx ); + // last updated 07jan2001 (gdl) /* *********************************************************************** * called from: monstuff |