From 61ebfeda71005384365b4598594e03bbdaec1e05 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Tue, 16 Dec 2008 03:58:13 +0000 Subject: Merge r7836: divine summons should drop non-summoned items on death (FR #2424917), summoned items should vanish when dropped/fired/thrown by monsters. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup-0.4@7844 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/beam.cc | 12 ++++++++++++ crawl-ref/source/makeitem.cc | 13 +++++++++---- crawl-ref/source/makeitem.h | 2 +- crawl-ref/source/mon-util.cc | 45 ++++++++++++++++++++++++++++++++++++-------- crawl-ref/source/monplace.cc | 13 ++++++++----- crawl-ref/source/monstuff.cc | 2 +- crawl-ref/source/mstuff2.cc | 3 ++- 7 files changed, 70 insertions(+), 20 deletions(-) diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 20e762e6b9..7dc06695e4 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -3071,6 +3071,18 @@ void beam_drop_object( bolt &beam, item_def *item, int x, int y ) if (beam.is_tracer || beam.flavour != BEAM_MISSILE) return; + if (item->flags & ISFLAG_SUMMONED) + { + if (see_grid(x, y)) + { + mprf("%s disappears in a puff of smoke!", + item->name(DESC_CAP_THE).c_str()); + } + item_was_destroyed(*item, beam.beam_source); + + return; + } + if (YOU_KILL(beam.thrower) && !thrown_object_destroyed(item, x, y, false) || MON_KILL(beam.thrower) diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index 3239939309..a4a01cef01 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -3697,7 +3697,8 @@ static item_make_species_type _give_weapon(monsters *mon, int level, // Hands out ammunition fitting the monster's launcher (if any), or else any // throwable weapon depending on the monster type. static void _give_ammo(monsters *mon, int level, - item_make_species_type item_race) + item_make_species_type item_race, + bool mons_summoned) { // Note that item_race is not reset for this section. if (const item_def *launcher = mon->launcher()) @@ -3798,7 +3799,7 @@ static void _give_ammo(monsters *mon, int level, qty = 3 + random2(6); } } - if (one_chance_in(6)) + if (one_chance_in(6) && !mons_summoned) { weap_class = OBJ_MISSILES; weap_type = MI_THROWING_NET; @@ -3816,6 +3817,9 @@ static void _give_ammo(monsters *mon, int level, // fall through case MONS_HAROLD: // bounty hunters case MONS_JOZEF: // up to 5 nets + if (mons_summoned) + break; + weap_class = OBJ_MISSILES; weap_type = MI_THROWING_NET; qty = 1; @@ -4180,7 +4184,8 @@ void give_armour(monsters *mon, int level) mitm[thing_created].colour = force_colour; } -void give_item(int mid, int level_number) //mv: cleanup+minor changes +void give_item(int mid, int level_number, + bool mons_summoned) //mv: cleanup+minor changes { monsters *mons = &menv[mid]; @@ -4190,7 +4195,7 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes const item_make_species_type item_race = _give_weapon(mons, level_number); - _give_ammo(mons, level_number, item_race); + _give_ammo(mons, level_number, item_race, mons_summoned); give_armour(mons, 1 + level_number / 2); give_shield(mons, 1 + level_number / 2); } diff --git a/crawl-ref/source/makeitem.h b/crawl-ref/source/makeitem.h index b5d1889109..8236c84aae 100644 --- a/crawl-ref/source/makeitem.h +++ b/crawl-ref/source/makeitem.h @@ -28,7 +28,7 @@ int items( int allow_uniques, object_class_type force_class, int force_type, void item_colour( item_def &item ); void init_rod_mp(item_def &item); -void give_item(int mid, int level_number); +void give_item(int mid, int level_number, bool mons_summoned); jewellery_type get_random_ring_type(); jewellery_type get_random_amulet_type(); diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 12ce3a1b03..945f803c98 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -3585,32 +3585,61 @@ bool monsters::drop_item(int eslot, int near) if (index == NON_ITEM) return (true); + item_def &item(mitm[index]); + // Unequip equipped items before dropping them; unequip() prevents // cursed items from being removed. bool was_unequipped = false; if (eslot == MSLOT_WEAPON || eslot == MSLOT_ARMOUR || eslot == MSLOT_ALT_WEAPON && mons_wields_two_weapons(this)) { - if (!unequip(mitm[index], eslot, near)) + if (!unequip(item, eslot, near)) return (false); was_unequipped = true; } - const std::string iname = mitm[index].name(DESC_NOCAP_A); - if (!move_item_to_grid(&index, x, y)) + bool on_floor = true; + + if (item.flags & ISFLAG_SUMMONED) + { + on_floor = false; + + if (need_message(near)) + mprf("%s disappear%s in a puff of smoke as %s drops it!", + item.name(DESC_CAP_THE).c_str(), + item.quantity == 1 ? "s" : "", + name(DESC_NOCAP_THE).c_str()); + + item_was_destroyed(item, monster_index(this)); + } + else if (!move_item_to_grid(&index, x, y)) { // Re-equip item if we somehow failed to drop it. if (was_unequipped) - equip(mitm[index], eslot, near); + equip(item, eslot, near); return (false); } - if (mons_friendly(this)) - mitm[index].flags |= ISFLAG_DROPPED_BY_ALLY; + if (on_floor) + { + if (mons_friendly(this)) + item.flags |= ISFLAG_DROPPED_BY_ALLY; - if (need_message(near)) - mprf("%s drops %s.", name(DESC_CAP_THE).c_str(), iname.c_str()); + if (need_message(near)) + mprf("%s drops %s.", name(DESC_CAP_THE).c_str(), + item.name(DESC_NOCAP_A).c_str()); + + dungeon_feature_type feat = grd(pos()); + if (grid_destroys_items(feat)) + { + if ( player_can_hear(pos()) ) + mprf(MSGCH_SOUND, grid_item_destruction_message(feat)); + + item_was_destroyed(item, monster_index(this)); + unlink_item(index); + } + } inv[eslot] = NON_ITEM; return (true); diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 232e64da02..119887fefa 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -922,19 +922,23 @@ static int _place_monster_aux( const mgen_data &mg, menv[id].flags |= MF_JUST_SUMMONED; + // dur should always be 1-6 for monsters that can be abjured. + const bool summoned = mg.abjuration_duration >= 1 + && mg.abjuration_duration <= 6; + if (mg.cls == MONS_DANCING_WEAPON && mg.number != 1) // ie not from spell { - give_item( id, mg.power ); + give_item( id, mg.power, summoned ); if (menv[id].inv[MSLOT_WEAPON] != NON_ITEM) menv[id].colour = mitm[ menv[id].inv[MSLOT_WEAPON] ].colour; } else if (mons_itemuse(mg.cls) >= MONUSE_STARTING_EQUIPMENT) { - give_item( id, mg.power ); + give_item( id, mg.power, summoned ); // Give these monsters a second weapon -- bwr if (mons_wields_two_weapons(mg.cls)) - give_item( id, mg.power ); + give_item( id, mg.power, summoned ); unwind_var save_speedinc(menv[id].speed_increment); menv[id].wield_melee_weapon(false); @@ -970,8 +974,7 @@ static int _place_monster_aux( const mgen_data &mg, menv[id].behaviour = BEH_WANDER; } - // dur should always be 1-6 for monsters that can be abjured. - if (mg.abjuration_duration >= 1 && mg.abjuration_duration <= 6) + if (summoned) menv[id].mark_summoned( mg.abjuration_duration, true ); menv[id].foe = mg.foe; diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index c23d93098f..23b3184db8 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -713,7 +713,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) const bool gives_xp = !monster->has_ench(ENCH_ABJ); bool in_transit = false; - bool drop_items = !hard_reset && !mons_is_holy(monster); + bool drop_items = !hard_reset; #ifdef DGL_MILESTONES _check_kill_milestone(monster, killer, i); diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index dbf42916b3..804f141895 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -1582,7 +1582,8 @@ bool mons_thrown_object_destroyed( item_def *item, int x, int y, if (returning && !destroyed) hostile_grid = false; - if (hostile_grid) + // Summoned items go poof if they're not returning. + if (hostile_grid || !returning && (item->flags & ISFLAG_SUMMONED)) { // No destruction sound here. Too much message spam otherwise. item_was_destroyed(*item, midx); -- cgit v1.2.3