diff options
-rw-r--r-- | crawl-ref/source/beam.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 15 | ||||
-rw-r--r-- | crawl-ref/source/itemname.cc | 1 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.cc | 10 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 19 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.cc | 31 |
8 files changed, 71 insertions, 12 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 89d3bb0c3d..fee514c479 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -3633,7 +3633,7 @@ static int affect_monster(bolt &beam, monsters *mon) if (player_monster_visible( &menv[tid] ) && mons_near(mon)) { msg::stream << "The " << beam.name << " misses " - << str_monam(*mon, DESC_NOCAP_THE) << std::endl; + << mon->name(DESC_NOCAP_THE) << '.' << std::endl; } return (0); } diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index f0c36af87f..11f49aabd4 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -3172,6 +3172,7 @@ enum brand_type // equivalent to (you.inv[].special or mitm[].special) % 30 SPWPN_PAIN, // 15 SPWPN_DISTORTION, SPWPN_REACHING, // 17 + SPWPN_RETURNING, SPWPN_CONFUSE, SPWPN_RANDART_I = 25, // 25 SPWPN_RANDART_II, diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index a9df7881e1..676fb0cbd1 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -514,6 +514,10 @@ void wield_effects(int item_wield_2, bool showMsgs) mpr("You sense a holy aura."); break; + case SPWPN_RETURNING: + mpr("It wiggles slightly."); + break; + case SPWPN_PAIN: mpr("A searing pain shoots up your arm!"); break; @@ -1367,6 +1371,7 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus) int dice_mult = 100; bool launched = false; // item is launched bool thrown = false; // item is sensible thrown item + bool returning = false; // item will return to pack int slayDam = 0; if (!teleport) @@ -1790,6 +1795,8 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus) // CALCULATIONS FOR THROWN WEAPONS if (thrown) { + returning = (get_weapon_brand(item) == SPWPN_RETURNING && + !one_chance_in(you.skills[SK_RANGED_COMBAT]+1)); baseHit = 0; // since darts/rocks are missiles, they only use inv_plus @@ -1994,10 +2001,14 @@ bool throw_it(struct bolt &pbolt, int throw_2, bool teleport, int acc_bonus) { // Dropping item copy, since the launched item might be different // (e.g. venom blowgun) - fire_beam( pbolt, &item ); + fire_beam(pbolt, returning ? NULL : &item); } - dec_inv_item_quantity( throw_2, 1 ); + if ( returning ) + msg::stream << item.name(DESC_CAP_THE) << " returns to your pack!" + << std::endl; + else + dec_inv_item_quantity( throw_2, 1 ); // throwing and blowguns are silent if (launched && lnchType != WPN_BLOWGUN) diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index c9344ea041..c1c12dba56 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -301,6 +301,7 @@ static const char* weapon_brand_name(const item_def& item, bool terse) case SPWPN_PAIN: return ((terse) ? " (pain)" : " of pain"); case SPWPN_DISTORTION: return ((terse) ? " (distort)" : " of distortion"); case SPWPN_REACHING: return ((terse) ? " (reach)" : " of reaching"); + case SPWPN_RETURNING: return ((terse) ? " (return)" : " of returning"); case SPWPN_VAMPIRICISM: return ((terse) ? " (vamp)" : ""); // non-terse already handled diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index f11995ae42..b65ee8991a 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -1324,6 +1324,9 @@ int items( int allow_uniques, // not just true-false, case WPN_DAGGER: + if (one_chance_in(4)) + set_weapon_special(p, SPWPN_RETURNING); + if (one_chance_in(10)) set_weapon_special(p, SPWPN_PAIN); @@ -1434,6 +1437,10 @@ int items( int allow_uniques, // not just true-false, if (one_chance_in(10)) set_weapon_special(p, SPWPN_VAMPIRICISM); + if (mitm[p].sub_type == WPN_HAND_AXE && + one_chance_in(10)) + set_weapon_special(p, SPWPN_RETURNING); + if (got_distortion_roll(item_level)) set_weapon_special(p, SPWPN_DISTORTION); @@ -1504,6 +1511,9 @@ int items( int allow_uniques, // not just true-false, if (one_chance_in(10)) set_weapon_special(p, SPWPN_VAMPIRICISM); + if (mitm[p].sub_type == WPN_SPEAR && one_chance_in(6)) + set_weapon_special(p, SPWPN_RETURNING); + if (got_distortion_roll(item_level)) set_weapon_special(p, SPWPN_DISTORTION); diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 1f9fe7951b..7cfbcb5cc0 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -1980,6 +1980,10 @@ bool mons_has_ranged_attack( const monsters *mon ) const int weapon = mon->inv[MSLOT_WEAPON]; const int ammo = mon->inv[MSLOT_MISSILE]; + if ( weapon != NON_ITEM && + get_weapon_brand(mitm[weapon]) == SPWPN_RETURNING ) + return true; + const int lnchClass = (weapon != NON_ITEM) ? mitm[weapon].base_type : -1; const int lnchType = (weapon != NON_ITEM) ? mitm[weapon].sub_type : 0; diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index dd00ba6fef..4ca9b40d29 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -3274,7 +3274,22 @@ static bool handle_throw(monsters *monster, bolt & beem) if (mons_itemuse(monster->type) < MONUSE_OPEN_DOORS) return (false); - const int mon_item = monster->inv[MSLOT_MISSILE]; + int mon_item; + const int mon_wpn = monster->inv[MSLOT_WEAPON]; + bool returning = false; + + // weapons of returning can be thrown + if ( mon_wpn != NON_ITEM && + get_weapon_brand(mitm[mon_wpn]) == SPWPN_RETURNING ) + { + mon_item = mon_wpn; + returning = true; + } + else + { + mon_item = monster->inv[MSLOT_MISSILE]; + } + if (mon_item == NON_ITEM || !is_valid_item( mitm[mon_item] )) return (false); @@ -3308,7 +3323,7 @@ static bool handle_throw(monsters *monster, bolt & beem) throw_type( lnchClass, lnchType, wepClass, wepType, launched, thrown ); - if (!launched && !thrown) + if (!launched && !thrown && !returning) return (false); // ok, we'll try it. diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index 41edcb93c0..03444dfd20 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -1006,11 +1006,10 @@ void throw_type( int lnchClass, int lnchType, int wepClass, int wepType, bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) { - // this was assumed during cleanup down below: - ASSERT( hand_used == monster->inv[MSLOT_MISSILE] ); - // XXX: ugly hack, but avoids adding dynamic allocation to this code - static char throw_buff[ ITEMNAME_SIZE ]; + char throw_buff[ ITEMNAME_SIZE ]; + + bool returning = (get_weapon_brand(mitm[hand_used]) == SPWPN_RETURNING); int baseHit = 0, baseDam = 0; // from thrown or ammo int ammoHitBonus = 0, ammoDamBonus = 0; // from thrown or ammo @@ -1048,6 +1047,11 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) // figure out if we're thrown or launched throw_type( lnchClass, lnchType, wepClass, wepType, launched, thrown ); + if (returning) + { + launched = false; + thrown = true; + } // extract launcher bonuses due to magic if (launched) @@ -1280,11 +1284,24 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) scale_dice(pbolt.damage); // decrease inventory - fire_beam( pbolt, &item ); + bool really_returns; + if ( returning && !one_chance_in(mons_power(monster->type) + 3) ) + really_returns = true; + else + really_returns = false; + + fire_beam( pbolt, really_returns ? NULL : &item ); - if (dec_mitm_item_quantity( hand_used, 1 )) - monster->inv[MSLOT_MISSILE] = NON_ITEM; + if ( really_returns ) + { + msg::stream << "The weapon returns to " + << monster->name(DESC_NOCAP_THE) + << "'s hand!" << std::endl; + } + if ( !really_returns ) + if (dec_mitm_item_quantity( hand_used, 1 )) + monster->inv[returning ? MSLOT_WEAPON : MSLOT_MISSILE] = NON_ITEM; return (true); } // end mons_throw() |