diff options
-rw-r--r-- | crawl-ref/source/mon-util.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 34 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 48 | ||||
-rw-r--r-- | crawl-ref/source/spells3.cc | 53 | ||||
-rw-r--r-- | crawl-ref/source/spells3.h | 1 |
6 files changed, 96 insertions, 46 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index c7c01fa6ad..45b8cee9b3 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -7588,8 +7588,7 @@ bool monsters::can_drink_potion(potion_type ptype) const { case POT_HEALING: case POT_HEAL_WOUNDS: - return (holiness() != MH_UNDEAD - && holiness() != MH_NONLIVING + return (holiness() != MH_NONLIVING && holiness() != MH_PLANT); case POT_BLOOD: case POT_BLOOD_COAGULATED: diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 8355f48cab..322eea7130 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -295,7 +295,7 @@ void monster_drop_ething(monsters *monster, bool mark_item_origins, if (mons_friendly(monster) && is_valid_item(mitm[item])) mitm[item].flags |= ISFLAG_DROPPED_BY_ALLY; - move_item_to_grid( &item, monster->pos() ); + move_item_to_grid(&item, monster->pos()); if (mark_item_origins && is_valid_item(mitm[item])) origin_set_monster(mitm[item], monster); @@ -317,7 +317,6 @@ int fill_out_corpse(const monsters* monster, item_def& corpse, int summon_type; if (mons_is_summoned(monster, NULL, &summon_type) - || mons_enslaved_body_and_soul(monster) || (monster->flags & (MF_BANISHED | MF_HARD_RESET))) { return (-1); @@ -364,32 +363,36 @@ int fill_out_corpse(const monsters* monster, item_def& corpse, return (corpse_class); } -static void _place_monster_corpse(const monsters *monster, bool silent) +int place_monster_corpse(const monsters *monster, bool silent, + bool force) { item_def corpse; const int corpse_class = fill_out_corpse(monster, corpse); // Don't place a corpse? If a zombified monster is somehow capable // of leaving a corpse then always place it. - const bool force = mons_class_is_zombified(monster->type); + if (mons_class_is_zombified(monster->type)) + force = true; + if (corpse_class == -1 || (!force && coinflip())) - return; + return (-1); if (grid_destroys_items(grd(monster->pos()))) { item_was_destroyed(corpse); - return; + return (-1); } int o = get_item_slot(); if (o == NON_ITEM) - return; + return (-1); mitm[o] = corpse; origin_set_monster(mitm[o], monster); - // Don't care if 'o' is changed, and it shouldn't be (corpses don't stack). - move_item_to_grid( &o, monster->pos() ); + // Don't care if 'o' is changed, and it shouldn't be (corpses don't + // stack). + move_item_to_grid(&o, monster->pos()); if (see_grid(monster->pos())) { if (force && !silent) @@ -406,7 +409,9 @@ static void _place_monster_corpse(const monsters *monster, bool silent) && player_res_poison() <= 0); tutorial_dissection_reminder(!poison); } -} // end place_monster_corpse() + + return (o); +} static void _tutorial_inspect_kill() { @@ -1108,8 +1113,7 @@ void monster_die(monsters *monster, killer_type killer, silent = true; } - if (monster->type == MONS_FIRE_VORTEX && !wizard - && !mons_reset) + if (monster->type == MONS_FIRE_VORTEX && !wizard && !mons_reset) { place_cloud(CLOUD_FIRE, monster->pos(), 2 + random2(4), monster->kill_alignment()); @@ -1588,9 +1592,7 @@ void monster_die(monsters *monster, killer_type killer, else if (!mons_is_summoned(monster)) { if (mons_genus(monster->type) == MONS_MUMMY) - { _mummy_curse(monster, killer, killer_index); - } } _monster_die_cloud(monster, !mons_reset, silent, summoned, summon_type); @@ -1599,7 +1601,7 @@ void monster_die(monsters *monster, killer_type killer, { // Have to add case for disintegration effect here? {dlb} if (!summoned) - _place_monster_corpse(monster, silent); + place_monster_corpse(monster, silent); } if (!mons_reset && !crawl_state.arena) @@ -2145,7 +2147,7 @@ bool random_near_space(const coord_def& origin, coord_def& target, { coord_def delta(random2(14), random2(14)); - target = origin - coord_def(6,6) + delta; + target = origin - coord_def(6, 6) + delta; // Origin is not 'near'. if (target == origin) diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h index 382b435c5a..3cd58c1276 100644 --- a/crawl-ref/source/monstuff.h +++ b/crawl-ref/source/monstuff.h @@ -92,6 +92,9 @@ void monster_die(monsters *monster, killer_type killer, int fill_out_corpse(const monsters* monster, item_def& corpse, bool allow_weightless = false); +int place_monster_corpse(const monsters *monster, bool silent, + bool force = true); + void mons_check_pool(monsters *monster, const coord_def &oldpos, killer_type killer = KILL_NONE, int killnum = -1); diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index a9d702b595..3888571ccf 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -5549,58 +5549,68 @@ void yred_make_enslaved_soul(monsters *mon, bool force_hostile, _yred_souls_disappear(); const int type = mon->type; - const std::string name = + monster_type soul_type = mons_species(type); + const std::string whose = player_monster_visible(mon) ? apostrophise(mon->name(DESC_CAP_THE)) : "Its"; - const std::string name_plain = mon->name(DESC_PLAIN); - bool twisted = false; - - if ((allow_fail || mons_unusable_items(mon) > 0) && coinflip()) - twisted = true; + const std::string name = mon->name(DESC_PLAIN); + int corps = -1; + bool twisted = allow_fail && coinflip(); if (!quiet) { - mprf("%s soul %s.", name.c_str(), + mprf("%s soul %s.", whose.c_str(), twisted ? "becomes twisted" : "remains intact"); } if (twisted) { - mon->type = mons_zombie_size(mons_species(type)) == Z_BIG ? + mon->type = mons_zombie_size(soul_type) == Z_BIG ? MONS_ABOMINATION_LARGE : MONS_ABOMINATION_SMALL; - mon->base_monster = mons_species(mon->type); + mon->base_monster = MONS_PROGRAM_BUG; } else { + // Drop the monster's corpse, so that it can be properly + // re-equipped below. + corps = place_monster_corpse(mon, true, true); + mon->type = MONS_SPECTRAL_THING; - mon->base_monster = mons_species(type); + mon->base_monster = soul_type; } + // Drop the monster's equipment. + monster_drop_ething(mon); + define_monster(*mon); + mon->colour = EC_UNHOLY; + mon->flags |= MF_ENSLAVED_SOUL; + mon->flags |= MF_CREATED_FRIENDLY; + if (twisted) - { // Mark abominations as undead. mon->flags |= MF_HONORARY_UNDEAD; + else if (corps != -1) + { + // Re-equip spectral things. + equip_undead(mon->pos(), corps, monster_index(mon), + mon->base_monster); - monster_drop_ething(mon); + // Destroy the monster's corpse, as it's no longer needed. + destroy_item(corps); } - mon->colour = EC_UNHOLY; - mon->flags |= MF_ENSLAVED_SOUL; - - name_zombified_unique(mon, type, name_plain); + name_zombified_unique(mon, type, name); - // Wow, permanent enslaving! mon->attitude = !force_hostile ? ATT_FRIENDLY : ATT_HOSTILE; - mon->flags |= MF_CREATED_FRIENDLY; behaviour_event(mon, ME_ALERT, !force_hostile ? MHITNOT : MHITYOU); mons_make_god_gift(mon, GOD_YREDELEMNUL); if (!quiet) { - mprf("%s soul %s.", name.c_str(), + mprf("%s soul %s.", whose.c_str(), !force_hostile ? "is now yours" : "fights you"); } } diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 7119f0052e..3baaaa9999 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -639,7 +639,7 @@ static bool _animatable_remains(const item_def& item) && mons_class_can_be_zombified(item.plus)); } -// Try to equip the zombie/skeleton with the objects it died with. +// Try to equip the zombie/skeleton/etc. with the objects it died with. // This excludes items which were dropped by the player onto the corpse, // and corpses which were picked up and moved by the player, so the player // can't equip their undead slaves with items of their choice. @@ -650,15 +650,14 @@ static bool _animatable_remains(const item_def& item) // undead can be equipped with the second monster's items if the second // monster is either of the same type as the first, or if the second // monster wasn't killed by the player or a player's pet. -static void _equip_undead(const coord_def &a, int corps, int monster, - int monnum) +void equip_undead(const coord_def &a, int corps, int monster, int monnum) { monsters* mon = &menv[monster]; if (mons_class_itemuse(monnum) < MONUSE_STARTING_EQUIPMENT) return; - // If the player picked up and dropped the corpse then all its + // If the player picked up and dropped the corpse, then all its // original equipment fell off. if (mitm[corps].flags & ISFLAG_DROPPED) return; @@ -695,6 +694,8 @@ static void _equip_undead(const coord_def &a, int corps, int monster, objl = mitm[objl].link; } + const bool smart_undead = mons_intel(mon) >= I_NORMAL; + for (int i = item_list.size() - 1; i >= 0; --i) { objl = item_list[i]; @@ -732,15 +733,19 @@ static void _equip_undead(const coord_def &a, int corps, int monster, // weren't equipment the monster died with. return; } + else if (smart_undead) + mslot = MSLOT_ALT_WEAPON; else - // The undead are too stupid to switch between - // weapons. + { + // Stupid undead can't switch between weapons. continue; + } } } else mslot = MSLOT_WEAPON; break; + case OBJ_ARMOUR: mslot = equip_slot_to_mslot(get_armour_slot(item)); @@ -759,11 +764,40 @@ static void _equip_undead(const coord_def &a, int corps, int monster, mslot = MSLOT_GOLD; break; - // The undead are too stupid to use these. + // Stupid undead can't use wands. case OBJ_WANDS: + if (smart_undead) + { + mslot = MSLOT_WAND; + break; + } + continue; + + // Stupid undead can't use scrolls. case OBJ_SCROLLS: + if (smart_undead) + { + mslot = MSLOT_SCROLL; + break; + } + continue; + + // Stupid undead can't use potions. case OBJ_POTIONS: + if (smart_undead) + { + mslot = MSLOT_POTION; + break; + } + continue; + + // Stupid undead can't use miscellaneous objects. case OBJ_MISCELLANY: + if (smart_undead) + { + mslot = MSLOT_MISCELLANY; + break; + } continue; default: @@ -803,7 +837,7 @@ static bool _raise_remains(const coord_def &a, int corps, beh_type beha, static_cast<monster_type>(item.plus); const int number = (item.props.exists(MONSTER_NUMBER)) ? - item.props[MONSTER_NUMBER].get_short() : 0; + item.props[MONSTER_NUMBER].get_short() : 0; // Headless hydras cannot be raised, sorry. if (zombie_type == MONS_HYDRA && number == 0) @@ -827,6 +861,7 @@ static bool _raise_remains(const coord_def &a, int corps, beh_type beha, 0, 0, a, hitting, 0, god, zombie_type, number)); + if (mon_index != NULL) *mon_index = monster; @@ -837,7 +872,7 @@ static bool _raise_remains(const coord_def &a, int corps, beh_type beha, name_zombified_unique(&menv[monster], monnum, origin_monster_name(item)); - _equip_undead(a, corps, monster, monnum); + equip_undead(a, corps, monster, monnum); destroy_item(corps); diff --git a/crawl-ref/source/spells3.h b/crawl-ref/source/spells3.h index 3ab8babacb..0b0ec2bb02 100644 --- a/crawl-ref/source/spells3.h +++ b/crawl-ref/source/spells3.h @@ -128,6 +128,7 @@ bool cast_summon_horrible_things(int pow, god_type god = GOD_NO_GOD); /* *********************************************************************** * called from: ability - spell * *********************************************************************** */ +void equip_undead(const coord_def &a, int corps, int monster, int monnum); bool animate_remains(const coord_def &a, corpse_type class_allowed, beh_type beha, unsigned short hitting, god_type god = GOD_NO_GOD, bool actual = true, |