summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/externs.h1
-rw-r--r--crawl-ref/source/ghost.cc18
-rw-r--r--crawl-ref/source/ghost.h2
-rw-r--r--crawl-ref/source/mon-util.cc21
-rw-r--r--crawl-ref/source/monstuff.cc18
-rw-r--r--crawl-ref/source/xom.cc4
6 files changed, 45 insertions, 19 deletions
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index c310ce8d7c..b2738753b5 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1365,6 +1365,7 @@ public:
void ghost_init();
void pandemon_init();
void uglything_init();
+ void uglything_mutate();
void destroy_inventory();
void load_spells(mon_spellbook_type spellbook);
diff --git a/crawl-ref/source/ghost.cc b/crawl-ref/source/ghost.cc
index 5c6a0be674..f54346d35e 100644
--- a/crawl-ref/source/ghost.cc
+++ b/crawl-ref/source/ghost.cc
@@ -399,14 +399,20 @@ void ghost_demon::init_player_ghost()
add_spells();
}
-static unsigned char _ugly_thing_random_colour()
+static unsigned char _ugly_thing_random_colour(unsigned char not_colour)
{
const unsigned char colours[] =
{
CYAN, GREEN, RED, LIGHTGREY, BROWN, MAGENTA
};
- return (colours[random2(sizeof(colours) / sizeof(*colours))]);
+ unsigned char colour;
+
+ do
+ colour = (colours[random2(sizeof(colours) / sizeof(*colours))]);
+ while (colour == not_colour);
+
+ return (colour);
}
static mon_attack_flavour _ugly_thing_colour_to_flavour(unsigned char u_colour)
@@ -469,7 +475,7 @@ static mon_attack_flavour _ugly_thing_flavour_upgrade(mon_attack_flavour u_att_f
return (u_att_flav);
}
-void ghost_demon::init_ugly_thing(bool very_ugly)
+void ghost_demon::init_ugly_thing(bool very_ugly, bool mutate)
{
// Midpoint: 10, as in mon-data.h.
speed = 9 + random2(3);
@@ -507,8 +513,10 @@ void ghost_demon::init_ugly_thing(bool very_ugly)
att_type = att_types[random2(sizeof(att_types) / sizeof(*att_types))];
- // An ugly thing always gets a low-intensity colour.
- colour = _ugly_thing_random_colour();
+ // An ugly thing always gets a low-intensity colour. If we're
+ // mutating it, it always gets a different colour from what it had
+ // before.
+ colour = _ugly_thing_random_colour(mutate ? colour : BLACK);
// Pick a compatible attack flavour for this colour.
att_flav = _ugly_thing_colour_to_flavour(colour);
diff --git a/crawl-ref/source/ghost.h b/crawl-ref/source/ghost.h
index f7f9dafb96..ab06a80954 100644
--- a/crawl-ref/source/ghost.h
+++ b/crawl-ref/source/ghost.h
@@ -46,7 +46,7 @@ public:
void reset();
void init_random_demon();
void init_player_ghost();
- void init_ugly_thing(bool very_ugly);
+ void init_ugly_thing(bool very_ugly, bool mutate = false);
void ugly_thing_to_very_ugly_thing();
public:
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index c2d755fb99..20c92c8fa7 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -6350,6 +6350,13 @@ void monsters::uglything_init()
colour = ghost->colour;
}
+void monsters::uglything_mutate()
+{
+ simple_monster_message(this, " mutates!");
+ ghost->init_ugly_thing(type == MONS_VERY_UGLY_THING, true);
+ uglything_init();
+}
+
bool monsters::check_set_valid_home(const coord_def &place,
coord_def &chosen,
int &nvalid) const
@@ -7908,15 +7915,15 @@ bool monsters::mon_see_grid(const coord_def& p, bool reach) const
bool monsters::can_see(const actor *targ) const
{
if (this == targ)
- return visible_to(targ);
+ return (visible_to(targ));
if (!targ->visible_to(this))
return (false);
if (targ->atype() == ACT_PLAYER)
- return mons_near(this);
+ return (mons_near(this));
- return mon_see_grid(targ->pos());
+ return (mon_see_grid(targ->pos()));
}
bool monsters::can_mutate() const
@@ -7939,6 +7946,14 @@ bool monsters::mutate()
if (!can_mutate())
return (false);
+ // Special case: Polymorphing a (very) ugly thing will mutate it
+ // into a different (very) ugly thing.
+ if (type == MONS_UGLY_THING || type == MONS_VERY_UGLY_THING)
+ {
+ uglything_mutate();
+ return (true);
+ }
+
if (this->has_ench(ENCH_GLOWING_SHAPESHIFTER))
return (monster_polymorph(this, MONS_GLOWING_SHAPESHIFTER));
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 358b1da0c2..0a592798c2 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2077,7 +2077,7 @@ void alert_nearby_monsters(void)
}
}
-static bool _valid_morph( monsters *monster, int new_mclass )
+static bool _valid_morph(monsters *monster, int new_mclass)
{
const dungeon_feature_type current_tile = grd(monster->pos());
@@ -2095,10 +2095,10 @@ static bool _valid_morph( monsters *monster, int new_mclass )
}
// Various inappropriate polymorph targets.
- if (mons_class_holiness( new_mclass ) != mons_holiness( monster )
- || mons_class_flag( new_mclass, M_UNIQUE) // no uniques
- || mons_class_flag( new_mclass, M_NO_EXP_GAIN ) // not helpless
- || new_mclass == mons_species( monster->type ) // must be different
+ if (mons_class_holiness(new_mclass) != mons_holiness(monster)
+ || mons_class_flag(new_mclass, M_UNIQUE) // no uniques
+ || mons_class_flag(new_mclass, M_NO_EXP_GAIN) // not helpless
+ || new_mclass == mons_species(monster->type) // must be different
|| new_mclass == MONS_PROGRAM_BUG
// These require manual setting of mons.base_monster to indicate
@@ -2106,10 +2106,10 @@ static bool _valid_morph( monsters *monster, int new_mclass )
// which we currently aren't smart enough to handle.
|| mons_class_is_zombified(new_mclass)
- // These shouldn't happen anyways (demons unaffected + holiness check),
- // but if we ever do have polydemon, these will be needed:
- || new_mclass == MONS_PLAYER_GHOST
- || new_mclass == MONS_PANDEMONIUM_DEMON
+ // These require manual setting of the ghost demon struct to
+ // indicate their characteristics, which we currently aren't
+ // smart enough to handle.
+ || mons_is_ghost_demon(new_mclass)
// Only for use by game testers or in the arena.
|| new_mclass == MONS_TEST_SPAWNER
diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc
index b613ab0a4d..512d71086f 100644
--- a/crawl-ref/source/xom.cc
+++ b/crawl-ref/source/xom.cc
@@ -1332,7 +1332,9 @@ static bool _xom_polymorph_nearby_monster(bool helpful)
bool see_old = you.can_see(mon);
std::string old_name = mon->full_name(DESC_PLAIN);
- if (one_chance_in(8) && !mons_is_shapeshifter(mon)
+ if (one_chance_in(8)
+ && !mons_is_ghost_demon(mon->type)
+ && !mons_is_shapeshifter(mon)
&& mons_holiness(mon) == MH_NATURAL)
{
mon->add_ench(one_chance_in(3) ? ENCH_GLOWING_SHAPESHIFTER