diff options
-rw-r--r-- | crawl-ref/source/beam.cc | 16 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.cc | 13 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 60 | ||||
-rw-r--r-- | crawl-ref/source/monplace.cc | 13 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 51 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.cc | 73 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.h | 7 |
8 files changed, 171 insertions, 64 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 2bf23be891..da31322807 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -3003,6 +3003,22 @@ void beam_drop_object( bolt &beam, item_def *item, const coord_def& _p ) if (!in_bounds(p)) p = beam.pos; + if (item->flags & ISFLAG_SUMMONED) + { + if (see_grid(p)) + { + mprf("%s %s!", + item->name(DESC_CAP_THE).c_str(), + summoned_poof_msg(beam.beam_source, *item).c_str()); + } + item_was_destroyed(*item, beam.beam_source); + + beam.dropped_item = true; + beam.item_pos = p; + beam.item_index = NON_ITEM; + return; + } + // Conditions: beam is missile and not tracer. if (YOU_KILL(beam.thrower) && !thrown_object_destroyed(item, p, false) diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index ff1c2a7a7c..df03e7258d 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -3662,7 +3662,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()) @@ -3763,7 +3764,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; @@ -3781,6 +3782,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; @@ -4149,7 +4153,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]; @@ -4159,7 +4164,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 7335055592..08478e6258 100644 --- a/crawl-ref/source/makeitem.h +++ b/crawl-ref/source/makeitem.h @@ -27,7 +27,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 e95ef6729f..01197f79ea 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -3733,13 +3733,23 @@ bool monsters::could_wield(const item_def &item, bool ignore_brand, if (!ignore_brand) { + const int brand = get_weapon_brand(item); + + // Draconians won't use dragon slaying weapons. + if (brand == SPWPN_DRAGON_SLAYING && is_dragonkind(this, this)) + return (false); + + // Orcs won't use orc slaying weapons. + if (brand == SPWPN_ORC_SLAYING && is_orckind(this, this)) + return (false); + // Demonic/undead monsters won't use holy weapons. if (mons_is_unholy(this) && is_holy_item(item)) return (false); // Holy monsters won't use demonic or chaotic weapons. - if (mons_holiness(this) == MH_HOLY - && (is_evil_item(item) || get_weapon_brand(item) == SPWPN_CHAOS)) + if ((mons_holiness(this) == MH_HOLY || is_good_god(god)) + && (is_evil_item(item) || brand == SPWPN_CHAOS)) { return (false); } @@ -4111,32 +4121,62 @@ bool monsters::drop_item(int eslot, int near) if (item_index == NON_ITEM) return (true); + item_def &item(mitm[item_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[item_index], eslot, near)) + if (!unequip(item, eslot, near)) return (false); was_unequipped = true; } - const std::string iname = mitm[item_index].name(DESC_NOCAP_A); - if (!move_item_to_grid(&item_index, pos())) + bool on_floor = true; + + if (item.flags & ISFLAG_SUMMONED) + { + on_floor = false; + + if (need_message(near)) + mprf("%s %s as %s drops %s!", + item.name(DESC_CAP_THE).c_str(), + summoned_poof_msg(this, item).c_str(), + name(DESC_NOCAP_THE).c_str(), + item.quantity > 1 ? "them" : "it"); + + item_was_destroyed(item, mindex()); + } + else if (!move_item_to_grid(&item_index, pos())) { // Re-equip item if we somehow failed to drop it. if (was_unequipped) - equip(mitm[item_index], eslot, near); + equip(item, eslot, near); return (false); } - if (mons_friendly(this)) - mitm[item_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, mindex()); + unlink_item(item_index); + } + } inv[eslot] = NON_ITEM; return (true); diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index a95a26a04f..5e21057810 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -990,19 +990,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_class_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_class_wields_two_weapons(mg.cls)) - give_item(id, mg.power); + give_item(id, mg.power, summoned); unwind_var<int> save_speedinc(menv[id].speed_increment); menv[id].wield_melee_weapon(false); @@ -1038,8 +1042,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, mg.summon_type ); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 9c349d3d3a..0753e6dac4 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -920,60 +920,29 @@ void _monster_die_cloud(const monsters* monster, bool corpse, bool silent, if (!summoned) return; - std::string prefix; - std::string msg = " disappears in a puff of smoke!"; - cloud_type cloud = random_smoke_type(); - int dur = 1 + random2(3); - + std::string prefix = " "; if (corpse) { if (mons_weight(mons_species(monster->type)) == 0) return; - prefix = "'s corpse"; + prefix = "'s corpse "; } - switch(summon_type) - { - case SPELL_SHADOW_CREATURES: - msg = " disolves into shadows!"; - cloud = CLOUD_NONE; - break; - - case MON_SUMM_CHAOS: - msg = " degenerates into a cloud of primal chaos!"; - cloud = CLOUD_CHAOS; - break; - - case MON_SUMM_WRATH: - case MON_SUMM_AID: - if (is_good_god(monster->god)) - { - msg = " disolves into sparkling lights!"; - cloud = CLOUD_NONE; - } - break; - } + std::string msg = summoned_poof_msg(monster); + msg += "!"; - if (monster->god == GOD_XOM && one_chance_in(10) - || cloud != CLOUD_NONE && monster->type == MONS_CHAOS_SPAWN) - { - msg = " degenerates into a cloud of primal chaos!"; + cloud_type cloud = CLOUD_NONE; + if (msg.find("smoke") != std::string::npos) + cloud = random_smoke_type(); + else if (msg.find("chaos") != std::string::npos) cloud = CLOUD_CHAOS; - } - - if (mons_is_holy(monster) && summon_type != SPELL_SHADOW_CREATURES - && summon_type != MON_SUMM_CHAOS) - { - msg = " disolves into sparkling lights!"; - cloud = CLOUD_NONE; - } if (!silent) simple_monster_message(monster, (prefix + msg).c_str()); if (cloud != CLOUD_NONE) - place_cloud( cloud, monster->pos(), dur, + place_cloud( cloud, monster->pos(), 1 + random2(3), monster->kill_alignment() ); } @@ -1002,7 +971,7 @@ void monster_die(monsters *monster, killer_type killer, const bool gives_xp = !summoned && !mons_enslaved_body_and_soul(monster); - const bool drop_items = !hard_reset && !mons_is_holy(monster); + const bool drop_items = !hard_reset; const bool mons_reset( killer == KILL_RESET || killer == KILL_DISMISSED ); diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index 5c9407f0fe..f10d9c9d7b 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -1372,7 +1372,8 @@ bool mons_thrown_object_destroyed( item_def *item, const coord_def& where, 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); @@ -2538,3 +2539,73 @@ int clone_mons(const monsters* orig, bool quiet, bool* obvious, return (midx); } + +std::string summoned_poof_msg(const monsters* monster, bool plural) +{ + int summon_type = 0; + bool valid_mon = false; + if (monster != NULL && !invalid_monster(monster)) + { + (void) monster->is_summoned(NULL, &summon_type); + valid_mon = true; + } + + std::string msg = "disappear%s in a puff of smoke"; + bool no_chaos = false; + + switch(summon_type) + { + case SPELL_SHADOW_CREATURES: + msg = "disolve%s into shadows"; + no_chaos = true; + break; + + case MON_SUMM_CHAOS: + msg = "degenerate%s into a cloud of primal chaos"; + break; + + case MON_SUMM_WRATH: + case MON_SUMM_AID: + if (valid_mon && is_good_god(monster->god)) + { + msg = "disolve%s into sparkling lights"; + no_chaos = true; + } + break; + } + + if (valid_mon) + { + if (monster->god == GOD_XOM && !no_chaos && one_chance_in(10) + || monster->type == MONS_CHAOS_SPAWN) + { + msg = "degenerate%s into a cloud of primal chaos"; + } + + if (mons_is_holy(monster) && summon_type != SPELL_SHADOW_CREATURES + && summon_type != MON_SUMM_CHAOS) + { + msg = "disolve%s into sparkling lights"; + } + } + + // Conjugate. + msg = make_stringf(msg.c_str(), plural ? "" : "s"); + + return (msg); +} + +std::string summoned_poof_msg(const int midx, const item_def &item) +{ + if (midx == NON_MONSTER) + return summoned_poof_msg(NULL, item); + else + return summoned_poof_msg(&menv[midx], item); +} + +std::string summoned_poof_msg(const monsters* monster, const item_def &item) +{ + ASSERT(item.flags & ISFLAG_SUMMONED); + + return summoned_poof_msg(monster, item.quantity > 1); +} diff --git a/crawl-ref/source/mstuff2.h b/crawl-ref/source/mstuff2.h index 65e3d0d0bb..ce2966bc31 100644 --- a/crawl-ref/source/mstuff2.h +++ b/crawl-ref/source/mstuff2.h @@ -38,7 +38,10 @@ bool moth_incite_monsters(const monsters *mon); void mons_clear_trapping_net(monsters *mon); bool mons_clonable(const monsters* orig, bool needs_adjacent = true); -int clone_mons(const monsters* orig, bool quiet = false, - bool* obvious = NULL, coord_def pos = coord_def(0, 0) ); +int clone_mons(const monsters* orig, bool quiet = false, + bool* obvious = NULL, coord_def pos = coord_def(0, 0) ); +std::string summoned_poof_msg(const monsters* monster, bool plural = false); +std::string summoned_poof_msg(const int midx, const item_def &item); +std::string summoned_poof_msg(const monsters* monster, const item_def &item); #endif |