summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/mon-util.cc3
-rw-r--r--crawl-ref/source/monstuff.cc34
-rw-r--r--crawl-ref/source/monstuff.h3
-rw-r--r--crawl-ref/source/religion.cc48
-rw-r--r--crawl-ref/source/spells3.cc53
-rw-r--r--crawl-ref/source/spells3.h1
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,