summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573>2009-01-08 00:09:03 +0000
committerdolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573>2009-01-08 00:09:03 +0000
commit20bb21380e30bd6cf6c3959222404e85c26fff1c (patch)
tree1b34d63b2486ef3b635637e44367c24c65720896 /crawl-ref
parenta9cbe2e3d8d4bdc982061667a072a060a912134a (diff)
downloadcrawl-ref-20bb21380e30bd6cf6c3959222404e85c26fff1c.tar.gz
crawl-ref-20bb21380e30bd6cf6c3959222404e85c26fff1c.zip
Expand equip_undead() to handle smart undead as well as stupid undead,
and use it to equip Yred's enslaved intact souls. Also, allow undead capable of using items and drinking potions to drink potions of healing and heal wounds, since undead players can. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8310 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-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,