diff options
author | Jude Brown <bookofjude@users.sourceforge.net> | 2009-12-24 20:34:29 +1000 |
---|---|---|
committer | Jude Brown <bookofjude@users.sourceforge.net> | 2009-12-24 21:17:11 +1000 |
commit | 9fcc7c41761ea968d0da075f2974a8908a2ef19b (patch) | |
tree | 85c8495c846722906b4832ba3d5de430532d95f6 /crawl-ref/source/monster.cc | |
parent | bcc249f77c1459b75b7a4f96b018a15569e675b3 (diff) | |
download | crawl-ref-9fcc7c41761ea968d0da075f2974a8908a2ef19b.tar.gz crawl-ref-9fcc7c41761ea968d0da075f2974a8908a2ef19b.zip |
New (rakshasa) unique: Mara, Lord of Ilusions.
This re-uses several ideas from the Emerald Eye FR, and implements the
spell "Mislead": this grants the "Misled" status effect to the player,
and causes on-level monsters to appear (glyph, name and tile) to be
other monsters. Only their appearance is changed.
Healing potions and rain remove this status effect.
Mara also has a beefed-up version of the Rakshasa clone spell: it
instead creates an "exact" clone (slightly altered spells list, and
non-unique status for his clones). Only two will ever be created at
once.
Finally, he has the spell "Summon Player Ghost". This spell creates a
ghost of the player (though marked as a summon, meaning that it
(shouldn't) register a milestone, though it will be treated as a
self-ghost kill) that is hostile. Only one of these should be existant
at any one point in time.
I'm pretty sure that I haven't broken anything, but would definitely
appreciate someone sanity-checking this commit.
Known minor issue: Kirke's summon ugly things being cast while having
the Misled status causes them to show up with no glyph.
Diffstat (limited to 'crawl-ref/source/monster.cc')
-rw-r--r-- | crawl-ref/source/monster.cc | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 55b342a903..4cefe30857 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -326,6 +326,7 @@ int monsters::body_weight() const case MONS_SPECTRAL_WARRIOR: case MONS_ELECTRIC_GOLEM: case MONS_RAKSHASA_FAKE: + case MONS_MARA_FAKE: return (0); case MONS_ZOMBIE_SMALL: @@ -2039,10 +2040,14 @@ static std::string _invalid_monster_str(monster_type type) static std::string _str_monam(const monsters& mon, description_level_type desc, bool force_seen) { - if (mon.type == MONS_NO_MONSTER) + monster_type type = mon.type; + if (!crawl_state.arena && you.misled()) + type = mon.get_mislead_type(); + + if (type == MONS_NO_MONSTER) return ("DEAD MONSTER"); - else if (invalid_monster_type(mon.type) && mon.type != MONS_PROGRAM_BUG) - return _invalid_monster_str(mon.type); + else if (invalid_monster_type(type) && type != MONS_PROGRAM_BUG) + return _invalid_monster_str(type); const bool arena_submerged = crawl_state.arena && !force_seen && mon.submerged(); @@ -2065,10 +2070,10 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, // Various special cases: // non-gold mimics, dancing weapons, ghosts, Pan demons - if (mons_is_mimic(mon.type)) + if (mons_is_mimic(type)) return (get_mimic_item(&mon).name(desc)); - if (mon.type == MONS_DANCING_WEAPON && mon.inv[MSLOT_WEAPON] != NON_ITEM) + if (type == MONS_DANCING_WEAPON && mon.inv[MSLOT_WEAPON] != NON_ITEM) { unsigned long ignore_flags = ISFLAG_KNOW_CURSE | ISFLAG_KNOW_PLUSES; bool use_inscrip = true; @@ -2085,16 +2090,16 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, } if (desc == DESC_DBNAME) - return (get_monster_data(mon.type)->name); + return (get_monster_data(type)->name); - if (mon.type == MONS_PLAYER_GHOST) + if (type == MONS_PLAYER_GHOST) return (apostrophise(mon.mname) + " ghost"); // Some monsters might want the name of a different creature. - monster_type nametype = mon.type; + monster_type nametype = type; // Tack on other prefixes. - switch (mon.type) + switch (type) { case MONS_ZOMBIE_SMALL: case MONS_ZOMBIE_LARGE: case MONS_SKELETON_SMALL: case MONS_SKELETON_LARGE: @@ -2159,7 +2164,7 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, result += "submerged "; // Tack on other prefixes. - switch (mon.type) + switch (type) { case MONS_UGLY_THING: case MONS_VERY_UGLY_THING: @@ -2185,7 +2190,7 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, break; } - if (mon.type == MONS_SLIME_CREATURE && desc != DESC_DBNAME) + if (type == MONS_SLIME_CREATURE && desc != DESC_DBNAME) { ASSERT(mon.number <= 5); const char* cardinals[] = {"buggy ", "", "large ", "very large ", @@ -2193,7 +2198,7 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, result += cardinals[mon.number]; } - if (mon.type == MONS_BALLISTOMYCETE && desc != DESC_DBNAME) + if (type == MONS_BALLISTOMYCETE && desc != DESC_DBNAME) { result += mon.number ? "active " : ""; } @@ -2231,7 +2236,7 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, } // Add suffixes. - switch (mon.type) + switch (type) { case MONS_ZOMBIE_SMALL: case MONS_ZOMBIE_LARGE: @@ -2260,7 +2265,7 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, result.insert(1, "n"); } - if (mons_is_unique(mon.type) && starts_with(result, "the ")) + if (mons_is_unique(type) && starts_with(result, "the ")) { switch (desc) { @@ -2278,7 +2283,7 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, { // If momentarily in original form, don't display "shaped // shifter". - if (mons_genus(mon.type) != MONS_SHAPESHIFTER) + if (mons_genus(type) != MONS_SHAPESHIFTER) result += " shaped shifter"; } @@ -2350,7 +2355,10 @@ std::string monsters::full_name(description_level_type desc, } } - const int _type = mons_is_zombified(this) ? base_monster : type; + int _type = mons_is_zombified(this) ? base_monster : type; + if (!crawl_state.arena && you.misled()) + _type = get_mislead_type(); + if (mons_genus(_type) == MONS_HYDRA && flag == 0) return (title); @@ -3720,7 +3728,11 @@ void monsters::ghost_init() enchantments.clear(); ench_countdown = 0; - find_place_to_live(); + // Summoned player ghosts are already given a position; calling this + // in those instances will cause a segfault. Instead, check to see + // if we have a home first. {due} + if (!in_bounds(pos())) + find_place_to_live(); } void monsters::uglything_init(bool only_mutate) @@ -5705,6 +5717,14 @@ const monsterentry *monsters::find_monsterentry() const : get_monster_data(type); } +monster_type monsters::get_mislead_type() const +{ + if (props.exists("mislead_as")) + return static_cast<monster_type>(props["mislead_as"].get_short()); + else + return type; +} + int monsters::action_energy(energy_use_type et) const { bool swift = has_ench(ENCH_SWIFT); |