summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-24 09:35:03 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-04-24 09:35:03 +0000
commit904a64bbcff41f7ecde8de133ddf68eeb2a8959f (patch)
tree0ed2875917488e791faadd9d7fb629d62b8594ee /crawl-ref/source
parent49271d835b9ebb39bcfdae8acbc644aeff6f2f3c (diff)
downloadcrawl-ref-904a64bbcff41f7ecde8de133ddf68eeb2a8959f.tar.gz
crawl-ref-904a64bbcff41f7ecde8de133ddf68eeb2a8959f.zip
* Add a wizard function apply_monster_blessing to allow for easy testing
of dolorous' fabulous blessing routines. * Allow the possibility of naming monsters: A monster's random name seed is stored in its number property, and the actual name gets picked from randname.txt. (Once this leaves the experimental stage I'll move them into a file of their own.) This means that monster types that already use number for something else (hydras for #heads, manticores for #spikes, or zombies for monster type) cannot be named. Use the new functions for naming orcs blessed by Beogh. Only non-generic orcs may get named, e.g. orcs promoted to priesthood or orc warriors that get their weapon enchanted. I tried to come up with a number of thematic orcish names, and if anyone would like to contribute, they're welcome to do so. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4586 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/dat/database/randname.txt90
-rw-r--r--crawl-ref/source/debug.cc35
-rw-r--r--crawl-ref/source/debug.h1
-rw-r--r--crawl-ref/source/describe.cc6
-rw-r--r--crawl-ref/source/directn.cc22
-rw-r--r--crawl-ref/source/enum.h27
-rw-r--r--crawl-ref/source/mon-util.cc195
-rw-r--r--crawl-ref/source/mon-util.h17
-rw-r--r--crawl-ref/source/monstuff.cc18
-rw-r--r--crawl-ref/source/mtransit.cc3
-rw-r--r--crawl-ref/source/mutation.cc4
-rw-r--r--crawl-ref/source/randart.cc4
-rw-r--r--crawl-ref/source/religion.cc41
-rw-r--r--crawl-ref/source/religion.h3
14 files changed, 381 insertions, 85 deletions
diff --git a/crawl-ref/source/dat/database/randname.txt b/crawl-ref/source/dat/database/randname.txt
index f8838e60f6..50ba8f6033 100644
--- a/crawl-ref/source/dat/database/randname.txt
+++ b/crawl-ref/source/dat/database/randname.txt
@@ -686,3 +686,93 @@ w:160
@general appearance@
%%%%
+##############################################
+# monster names
+##############################################
+orc name
+
+# Some important syllables
+# beogh, bog = referring to Beogh
+# ork, orc, org, ok, oc, og (and more) = referring to orcs
+#
+# Other syllables may be borrowed from real life, or made up.
+
+Albeogh
+
+Bogbart
+
+# slavic name, meaning "god's gift" :)
+Bogdan
+
+# Obvious references to Beogh
+Bogdar
+
+Bogmar
+
+Bogward
+
+Bogwik
+
+Morbeogh
+
+Sharbog
+
+# Obvious references to orcs in general
+Alork
+
+Boruk
+
+Marbork
+
+Milork
+
+Okrist
+
+Oreg
+
+Orik
+
+Orkrul
+
+Orkwin
+
+Oruk
+
+# Other
+Agrik
+
+Arbolt
+
+Arkwar
+
+Berold
+
+Dorog
+
+Gorbash
+
+Gorg
+
+Learuk
+
+Margrim
+
+Morun
+
+Murdo
+
+Norbak
+
+Olfik
+
+Olfrun
+
+Wardok
+
+Worak
+
+Wulfoc
+
+Zoruk
+
+%%%% \ No newline at end of file
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index 6783f205ae..530ed34686 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -3477,7 +3477,6 @@ extern void force_monster_shout(monsters* monster);
void debug_make_monster_shout(monsters* mon)
{
-
mpr("Make the monster (S)hout or (T)alk?", MSGCH_PROMPT);
char type = (char) getchm(KC_DEFAULT);
@@ -3513,13 +3512,17 @@ void debug_make_monster_shout(monsters* mon)
mpr("The monster is invisible and likely won't speak.");
if (silenced(you.x_pos, you.y_pos) && !silenced(mon->x, mon->y))
+ {
mpr("You are silenced but the monster isn't; you will "
"probably hear/see nothing.");
+ }
else if (!silenced(you.x_pos, you.y_pos) && silenced(mon->x, mon->y))
mpr("The monster is silenced and likely won't say anything.");
else if (silenced(you.x_pos, you.y_pos) && silenced(mon->x, mon->y))
+ {
mpr("Both you and the monster are silenced, so you likely "
"won't hear anything.");
+ }
for (int i = 0; i< num_times; i++)
mons_speaks(mon);
@@ -3530,6 +3533,36 @@ void debug_make_monster_shout(monsters* mon)
#endif
#ifdef WIZARD
+static bool _force_suitable(const monsters *mon)
+{
+ return (mon->alive());
+}
+
+void debug_apply_monster_blessing(monsters* mon)
+{
+ mpr("Apply blessing of (B)eogh, The (S)hining One, or (R)andomly?",
+ MSGCH_PROMPT);
+
+ char type = (char) getchm(KC_DEFAULT);
+ type = tolower(type);
+
+ if (type != 'b' && type != 's' && type != 'r')
+ {
+ canned_msg( MSG_OK );
+ return;
+ }
+ god_type god = GOD_NO_GOD;
+ if (type == 'b' || type == 'r' && coinflip())
+ god = GOD_BEOGH;
+ else
+ god = GOD_SHINING_ONE;
+
+ if (!bless_follower(mon, god, _force_suitable, true))
+ mprf("%s won't bless this monster for you!", god_name(god).c_str());
+}
+#endif
+
+#ifdef WIZARD
void wizard_give_monster_item(monsters *mon)
{
mon_itemuse_type item_use = mons_itemuse( mon->type );
diff --git a/crawl-ref/source/debug.h b/crawl-ref/source/debug.h
index 2e391f5ffe..f9bb6cc568 100644
--- a/crawl-ref/source/debug.h
+++ b/crawl-ref/source/debug.h
@@ -162,6 +162,7 @@ void debug_dismiss_all_monsters(bool force_all = false);
class monsters;
void debug_make_monster_shout(monsters* mon);
+void debug_apply_monster_blessing(monsters* mon);
void wizard_give_monster_item(monsters* mon);
#ifdef DEBUG_DIAGNOSTICS
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 1e993a65bd..f65f5b864f 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -2067,7 +2067,11 @@ void describe_monsters(monsters& mons)
}
std::ostringstream description;
- description << mons.name(DESC_CAP_A) << "$$";
+ std::string name = get_unique_monster_name(&mons);
+ if (name.empty())
+ name = mons.name(DESC_CAP_A);
+
+ description << name << "$$";
// Note: Nearly all of the "long" descriptions have moved to
// mon-data.h, in an effort to give them some locality with the
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index 95df12ab38..e850614da4 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -862,12 +862,22 @@ void direction(dist& moves, targeting_type restricts,
}
// To update visual branding of friendlies. Only
- // seem capabable of adding bolding, not removing it,
+ // seems capabable of adding bolding, not removing it,
// though.
viewwindow(true, false);
}
break;
+ case CMD_TARGET_WIZARD_BLESS_MONSTER:
+ if (!you.wizard || !in_bounds(moves.tx, moves.ty))
+ break;
+ mid = mgrd[moves.tx][moves.ty];
+ if (mid == NON_MONSTER) // can put in terrain description here
+ break;
+
+ debug_apply_monster_blessing(&menv[mid]);
+ break;
+
case CMD_TARGET_WIZARD_MAKE_SHOUT:
// Maybe we can skip this check...but it can't hurt
if (!you.wizard || !in_bounds(moves.tx, moves.ty))
@@ -2001,11 +2011,15 @@ static std::string describe_monster_weapon(const monsters *mons)
const item_def *alt = mons->mslot_item(MSLOT_ALT_WEAPON);
if (weap)
+ {
name1 = weap->name(DESC_NOCAP_A, false, false, true,
false, ISFLAG_KNOW_CURSE);
+ }
if (alt && (!weap || mons_wields_two_weapons(mons)))
+ {
name2 = alt->name(DESC_NOCAP_A, false, false, true,
false, ISFLAG_KNOW_CURSE);
+ }
if (name1.empty() && !name2.empty())
name1.swap(name2);
@@ -2151,7 +2165,10 @@ static void describe_monster(const monsters *mon)
std::string get_monster_desc(const monsters *mon, bool full_desc,
description_level_type mondtype)
{
- std::string desc = mon->name(mondtype);
+ std::string desc = get_unique_monster_name(mon);
+
+ if (desc.empty())
+ desc = mon->name(mondtype);
const int mon_arm = mon->inv[MSLOT_ARMOUR];
const int mon_shd = mon->inv[MSLOT_SHIELD];
@@ -2385,6 +2402,7 @@ command_type targeting_behaviour::get_command(int key)
#ifdef WIZARD
case 'F': return CMD_TARGET_WIZARD_MAKE_FRIENDLY;
+ case 'P': return CMD_TARGET_WIZARD_BLESS_MONSTER;
case 's': return CMD_TARGET_WIZARD_MAKE_SHOUT;
case 'g': return CMD_TARGET_WIZARD_GIVE_ITEM;
#endif
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index a14f6fc23f..4e4b8885f2 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -74,12 +74,12 @@ enum ability_type
ABIL_END_TRANSFORMATION, // 55
// Divine abilities
- ABIL_ZIN_RECITE = 110, // 110
+ ABIL_ZIN_RECITE = 110, // 110
ABIL_ZIN_REVITALISATION,
ABIL_ZIN_SANCTUARY,
- ABIL_TSO_DIVINE_SHIELD = 120, // 120
+ ABIL_TSO_DIVINE_SHIELD = 120, // 120
ABIL_TSO_CLEANSING_FLAME,
- ABIL_TSO_SUMMON_DAEVA, // 122
+ ABIL_TSO_SUMMON_DAEVA, // 122
ABIL_KIKU_RECALL_UNDEAD_SLAVES = 130, // 130
ABIL_KIKU_ENSLAVE_UNDEAD = 132, // 132
ABIL_KIKU_INVOKE_DEATH, // 133
@@ -92,34 +92,34 @@ enum ability_type
ABIL_OKAWARU_MIGHT = 170, // 170
// Okawaru no longer heals (JPEG)
ABIL_OKAWARU_HASTE = 172, // 172
- ABIL_MAKHLEB_MINOR_DESTRUCTION = 180, // 180
+ ABIL_MAKHLEB_MINOR_DESTRUCTION = 180, // 180
ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB,
ABIL_MAKHLEB_MAJOR_DESTRUCTION,
- ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB, // 183
- ABIL_SIF_MUNA_CHANNEL_ENERGY = 190, // 190
+ ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB,// 183
+ ABIL_SIF_MUNA_CHANNEL_ENERGY = 190, // 190
ABIL_SIF_MUNA_FORGET_SPELL,
ABIL_TROG_BURN_BOOKS = 199,
- ABIL_TROG_BERSERK = 200, // 200
+ ABIL_TROG_BERSERK = 200, // 200
ABIL_TROG_REGENERATION,
- ABIL_TROG_BROTHERS_IN_ARMS, // 202
+ ABIL_TROG_BROTHERS_IN_ARMS, // 202
ABIL_ELYVILON_DESTROY_WEAPONS = 219,
- ABIL_ELYVILON_LESSER_HEALING = 220, // 220
+ ABIL_ELYVILON_LESSER_HEALING = 220, // 220
ABIL_ELYVILON_PURIFICATION,
ABIL_ELYVILON_HEALING,
ABIL_ELYVILON_RESTORATION,
- ABIL_ELYVILON_GREATER_HEALING, // 224
+ ABIL_ELYVILON_GREATER_HEALING, // 224
ABIL_LUGONU_ABYSS_EXIT,
ABIL_LUGONU_BEND_SPACE,
ABIL_LUGONU_BANISH,
ABIL_LUGONU_CORRUPT,
- ABIL_LUGONU_ABYSS_ENTER,
+ ABIL_LUGONU_ABYSS_ENTER, // 229
ABIL_NEMELEX_DRAW_ONE,
ABIL_NEMELEX_PEEK_TWO,
ABIL_NEMELEX_TRIPLE_DRAW,
ABIL_NEMELEX_MARK_FOUR,
- ABIL_NEMELEX_STACK_FIVE,
+ ABIL_NEMELEX_STACK_FIVE, // 234
ABIL_BEOGH_SMITING,
- ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS,
+ ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS, // 236
ABIL_CHARM_SNAKE,
ABIL_TRAN_SERPENT_OF_HELL,
@@ -592,6 +592,7 @@ enum command_type
CMD_TARGET_FIND_YOU,
CMD_TARGET_DESCRIBE,
CMD_TARGET_WIZARD_MAKE_FRIENDLY,
+ CMD_TARGET_WIZARD_BLESS_MONSTER,
CMD_TARGET_WIZARD_MAKE_SHOUT,
CMD_TARGET_WIZARD_GIVE_ITEM,
CMD_TARGET_HELP,
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index bc56df06f6..c6314be4f2 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -1651,7 +1651,7 @@ static std::string _str_monam(const monsters& mon, description_level_type desc,
switch (mon.type)
{
case MONS_SPECTRAL_THING:
- result += "spectral ";
+ result += "spectral ";
nametype = mon.number;
break;
@@ -1725,16 +1725,107 @@ std::string mons_type_name(int type, description_level_type desc )
result += get_monster_data(type)->name;
// Vowel fix: Change 'a orc' to 'an orc'
- if ( result.length() >= 3 &&
- (result[0] == 'a' || result[0] == 'A') &&
- result[1] == ' ' &&
- is_vowel(result[2]) )
+ if ( result.length() >= 3
+ && (result[0] == 'a' || result[0] == 'A')
+ && result[1] == ' '
+ && is_vowel(result[2]) )
{
result.insert(1, "n");
}
return result;
}
+// Fills the number parameter (if not otherwise needed) with a seed for
+// random name choice from randname.txt.
+bool give_unique_monster_name(monsters *mon, bool higher_orcs_only)
+{
+ // already have a name
+ if (mons_is_unique(mon->type) || mon->type == MONS_PLAYER_GHOST
+ || mon->type == MONS_PANDEMONIUM_DEMON)
+ {
+ return false;
+ }
+
+ // need their number parameter for other information
+ if (mon->type == MONS_HYDRA // #heads
+ || mon->type == MONS_ABOMINATION_SMALL // colour
+ || mon->type == MONS_ABOMINATION_LARGE // colour
+ || mon->type == MONS_MANTICORE // #spikes
+ || mons_genus(mon->type) == MONS_DRACONIAN // subspecies
+ || mons_class_is_zombified(mon->type)) // zombie type
+ {
+ return false;
+ }
+
+ // Since this is called from the various divine blessing routines,
+ // don't bless non-orcs, and don't bless plain orcs, either.
+ if (higher_orcs_only
+ && (mons_species(mon->type) != MONS_ORC || mon->type == MONS_ORC))
+ {
+ return false;
+ }
+
+ // already has a unique name
+ if (mon->number > 0 && mon->number != MONS_PROGRAM_BUG)
+ return false;
+
+ // randomly pick a number
+ // XXX: Why does unsigned int (number's type) get munged on save & reload?
+ mon->number = (unsigned char) random_int();
+// mprf(MSGCH_DIAGNOSTICS, "new monster number is %d", mon->number);
+
+ return (mon->number != 0 && mon->number != MONS_PROGRAM_BUG);
+}
+
+std::string get_unique_monster_name(const monsters *mon)
+{
+ if (mons_is_unique(mon->type))
+ return get_monster_data(mon->type)->name;
+
+ if (mon->type == MONS_PLAYER_GHOST)
+ return mon->ghost->name + "'s ghost";
+
+ if (mon->type == MONS_PANDEMONIUM_DEMON)
+ return mon->ghost->name;
+
+ // Since the seed for the monster name is stored in mon->number
+ // any monster that uses number for something else cannot be named.
+ if (mon->type == MONS_HYDRA // #heads
+ || mon->type == MONS_ABOMINATION_SMALL // colour
+ || mon->type == MONS_ABOMINATION_LARGE // colour
+ || mon->type == MONS_MANTICORE // #spikes
+ || mons_genus(mon->type) == MONS_DRACONIAN // subspecies
+ || mons_class_is_zombified(mon->type)) // zombie type
+ {
+ return "";
+ }
+
+ // unnamed, sorry
+ if (mon->number <= 0 || mon->number == MONS_PROGRAM_BUG)
+ return "";
+
+// mprf(MSGCH_DIAGNOSTICS, "get name from number %d", mon->number);
+
+ rng_save_excursion rng_state;
+ seed_rng( mon->number );
+
+ std::string name
+ = getRandNameString(get_monster_data(mon->type)->name, " name");
+
+ if (!name.empty())
+ return name;
+
+ name = getRandNameString(get_monster_data(mons_genus(mon->type))->name,
+ " name");
+
+ if (!name.empty())
+ return name;
+
+ name = getRandNameString("generic_monster_name");
+
+ return name;
+}
+
/* ********************* END PUBLIC FUNCTIONS ********************* */
// see mons_init for initialization of mon_entry array.
@@ -2921,8 +3012,10 @@ void monsters::equip_weapon(item_def &item, int near)
void monsters::equip_armour(item_def &item, int near)
{
if (need_message(near))
+ {
mprf("%s wears %s.", name(DESC_CAP_THE).c_str(),
item.name(DESC_NOCAP_A).c_str());
+ }
const equipment_type eq = get_armour_slot(item);
if (eq != EQ_SHIELD)
@@ -2959,9 +3052,11 @@ void monsters::equip(item_def &item, int slot, int near)
void monsters::unequip_weapon(item_def &item, int near)
{
if (need_message(near))
+ {
mprf("%s unwields %s.", name(DESC_CAP_THE).c_str(),
item.name(DESC_NOCAP_A, false, false, true,
false, ISFLAG_CURSED).c_str());
+ }
const int brand = get_weapon_brand(item);
if (brand == SPWPN_PROTECTION)
@@ -3003,8 +3098,10 @@ void monsters::unequip_weapon(item_def &item, int near)
void monsters::unequip_armour(item_def &item, int near)
{
if (need_message(near))
+ {
mprf("%s takes off %s.", name(DESC_CAP_THE).c_str(),
item.name(DESC_NOCAP_A).c_str());
+ }
const equipment_type eq = get_armour_slot(item);
if (eq != EQ_SHIELD)
@@ -3483,8 +3580,10 @@ bool monsters::eat_corpse(item_def &carrion, int near)
max_hit_points = hit_points;
if (need_message(near))
+ {
mprf("%s eats %s.", name(DESC_CAP_THE).c_str(),
carrion.name(DESC_NOCAP_THE).c_str());
+ }
destroy_item( carrion.index() );
return (true);
@@ -3622,6 +3721,10 @@ item_def *monsters::shield()
std::string monsters::name(description_level_type desc) const
{
+ std::string monnam = get_unique_monster_name(this);
+ if (!monnam.empty())
+ return monnam;
+
return this->name(desc, false);
}
@@ -4009,37 +4112,39 @@ void monsters::set_ghost(const ghost_demon &g)
void monsters::pandemon_init()
{
- hit_dice = ghost->xl;
- hit_points = ghost->max_hp;
- max_hit_points = ghost->max_hp;
- ac = ghost->ac;
- ev = ghost->ev;
- speed = (one_chance_in(3) ? 10 : 8 + roll_dice(2, 9));
+ hit_dice = ghost->xl;
+ hit_points = ghost->max_hp;
+ max_hit_points = ghost->max_hp;
+ ac = ghost->ac;
+ ev = ghost->ev;
+ speed = (one_chance_in(3) ? 10 : 8 + roll_dice(2, 9));
speed_increment = 70;
+
if (you.char_direction == GDT_ASCENDING && you.level_type == LEVEL_DUNGEON)
colour = LIGHTRED;
else
colour = random_colour(); // demon's colour
+
load_spells(MST_GHOST);
}
void monsters::ghost_init()
{
- type = MONS_PLAYER_GHOST;
- hit_dice = ghost->xl;
- hit_points = ghost->max_hp;
- max_hit_points = ghost->max_hp;
- ac = ghost->ac;
- ev = ghost->ev;
- speed = ghost->speed;
+ type = MONS_PLAYER_GHOST;
+ hit_dice = ghost->xl;
+ hit_points = ghost->max_hp;
+ max_hit_points = ghost->max_hp;
+ ac = ghost->ac;
+ ev = ghost->ev;
+ speed = ghost->speed;
speed_increment = 70;
- attitude = ATT_HOSTILE;
- behaviour = BEH_WANDER;
- flags = 0;
- foe = MHITNOT;
- foe_memory = 0;
- colour = mons_class_colour(MONS_PLAYER_GHOST);
- number = MONS_PROGRAM_BUG;
+ attitude = ATT_HOSTILE;
+ behaviour = BEH_WANDER;
+ flags = 0;
+ foe = MHITNOT;
+ foe_memory = 0;
+ colour = mons_class_colour(MONS_PLAYER_GHOST);
+ number = MONS_PROGRAM_BUG;
load_spells(MST_GHOST);
inv.init(NON_ITEM);
@@ -4152,19 +4257,19 @@ void monsters::reset()
ench_countdown = 0;
inv.init(NON_ITEM);
- flags = 0;
- experience = 0L;
- type = -1;
- hit_points = 0;
- max_hit_points = 0;
- hit_dice = 0;
- ac = 0;
- ev = 0;
+ flags = 0;
+ experience = 0L;
+ type = -1;
+ hit_points = 0;
+ max_hit_points = 0;
+ hit_dice = 0;
+ ac = 0;
+ ev = 0;
speed_increment = 0;
- attitude = ATT_HOSTILE;
- behaviour = BEH_SLEEP;
- foe = MHITNOT;
- number = 0;
+ attitude = ATT_HOSTILE;
+ behaviour = BEH_SLEEP;
+ foe = MHITNOT;
+ number = 0;
if (in_bounds(x, y))
mgrd[x][y] = NON_MONSTER;
@@ -4190,7 +4295,7 @@ void monsters::set_transit(const level_id &dest)
void monsters::load_spells(mon_spellbook_type book)
{
spells.init(SPELL_NO_SPELL);
- if (book == MST_NO_SPELLS || (book == MST_GHOST && !ghost.get()))
+ if (book == MST_NO_SPELLS || book == MST_GHOST && !ghost.get())
return;
#if DEBUG_DIAGNOSTICS
@@ -5483,9 +5588,11 @@ void monsters::react_to_damage(int damage)
if (spawned == 1)
mprf("%s spits out another jelly.", mname.c_str());
else
+ {
mprf("%s spits out %s more jellies.",
mname.c_str(),
number_in_words(spawned).c_str());
+ }
}
}
}
@@ -5744,8 +5851,16 @@ std::string do_mon_str_replacements(const std::string &in_msg,
std::string msg = in_msg;
description_level_type nocap, cap;
- if (monster->attitude == ATT_FRIENDLY && !mons_is_unique(monster->type)
- && player_monster_visible(monster))
+ std::string name = get_unique_monster_name(monster);
+ if (!name.empty() && player_monster_visible(monster))
+ {
+ msg = replace_all(msg, "@the_something@", name);
+ msg = replace_all(msg, "@The_something@", name);
+ msg = replace_all(msg, "@the_monster@", name);
+ msg = replace_all(msg, "@The_monster@", name);
+ }
+ else if (monster->attitude == ATT_FRIENDLY && !mons_is_unique(monster->type)
+ && player_monster_visible(monster))
{
nocap = DESC_PLAIN;
cap = DESC_PLAIN;
diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h
index e7c87c66ba..ec0d7b3781 100644
--- a/crawl-ref/source/mon-util.h
+++ b/crawl-ref/source/mon-util.h
@@ -50,7 +50,7 @@ enum mon_attack_type
AT_CLAW,
AT_TAIL_SLAP,
AT_BUTT,
-
+
AT_SHOOT // attack representing missile damage for M_ARCHER
};
@@ -174,8 +174,8 @@ enum mon_resist_flags
{
MR_NO_FLAGS = 0,
- // resistances
- // Notes:
+ // resistances
+ // Notes:
// - negative energy is mostly handled via mons_res_negative_energy()
// - acid is handled mostly by genus (jellies) plus non-living
// - asphyx-resistance replaces hellfrost resistance.
@@ -193,7 +193,7 @@ enum mon_resist_flags
MR_VUL_FIRE = (1<< 9),
MR_VUL_COLD = (1<<10),
- // melee armour resists/vulnerabilities
+ // melee armour resists/vulnerabilities
// XXX: how to do combos (bludgeon/slice, bludgeon/pierce)
MR_RES_PIERCE = (1<<11),
MR_RES_SLICE = (1<<12),
@@ -211,7 +211,7 @@ enum mon_resist_flags
enum shout_type
{
S_SILENT, // silent
- S_SHOUT, // shout
+ S_SHOUT, // shout
S_BARK, // bark
S_SHOUT2, // shout twice (e.g. two-headed ogres)
S_ROAR, // roar
@@ -284,7 +284,7 @@ struct mon_resist_def
// All values are actually saved as single-bytes, so practical
// range is -128 - 127, and the game only distinguishes values in
// the range -1 to 3.
-
+
short elec;
short poison;
short fire;
@@ -383,7 +383,10 @@ void init_monster_symbols();
monsters *monster_at(const coord_def &pos);
// this is the old moname()
-std::string mons_type_name(int type, description_level_type desc );
+std::string mons_type_name(int type, description_level_type desc);
+
+bool give_unique_monster_name(monsters *mon, bool orc_only = true);
+std::string get_unique_monster_name(const monsters *mon);
// last updated 12may2000 {dlb}
/* ***********************************************************************
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index e022eadfdb..5ae594cb0a 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -1536,7 +1536,7 @@ bool monster_polymorph( monsters *monster, monster_type targetc,
update_beholders(monster, true);
// the actual polymorphing:
- const int old_hp = monster->hit_points;
+ const int old_hp = monster->hit_points;
const int old_hp_max = monster->max_hit_points;
const bool old_mon_shifter = monster->has_ench(ENCH_GLOWING_SHAPESHIFTER,
ENCH_SHAPESHIFTER);
@@ -1544,13 +1544,13 @@ bool monster_polymorph( monsters *monster, monster_type targetc,
const char old_ench_countdown = monster->ench_countdown;
// deal with mons_sec
- monster->type = targetc;
+ monster->type = targetc;
monster->number = MONS_PROGRAM_BUG;
- mon_enchant abj = monster->get_ench(ENCH_ABJ);
+ mon_enchant abj = monster->get_ench(ENCH_ABJ);
mon_enchant shifter = monster->get_ench(ENCH_GLOWING_SHAPESHIFTER,
ENCH_SHAPESHIFTER);
- mon_enchant charm = monster->get_ench(ENCH_CHARM);
+ mon_enchant charm = monster->get_ench(ENCH_CHARM);
// Note: define_monster() will clear out all enchantments! -- bwr
define_monster( monster_index(monster) );
@@ -2608,8 +2608,12 @@ bool simple_monster_message(const monsters *monster, const char *event,
&& (channel == MSGCH_MONSTER_SPELL || player_monster_visible(monster)))
{
char buff[INFO_SIZE];
- snprintf( buff, sizeof(buff), "%s%s",
- monster->name(descrip).c_str(), event );
+
+ std::string name = get_unique_monster_name(monster);
+ if (name.empty())
+ name = monster->name(descrip);
+
+ snprintf( buff, sizeof(buff), "%s%s", name.c_str(), event );
mpr( buff, channel, param );
return (true);
@@ -3152,7 +3156,7 @@ static bool _handle_special_ability(monsters *monster, bolt & beem)
fire_beam(beem);
used = true;
// decrement # of volleys left
- monster->number -= 1;
+ monster->number--;
}
break;
diff --git a/crawl-ref/source/mtransit.cc b/crawl-ref/source/mtransit.cc
index 2a9edda813..ab19b6f819 100644
--- a/crawl-ref/source/mtransit.cc
+++ b/crawl-ref/source/mtransit.cc
@@ -167,8 +167,7 @@ static void level_place_lost_monsters(m_transit_list &m)
static void level_place_followers(m_transit_list &m)
{
- for (m_transit_list::iterator i = m.begin();
- i != m.end(); )
+ for (m_transit_list::iterator i = m.begin(); i != m.end(); )
{
m_transit_list::iterator mon = i++;
if ((mon->mons.flags & MF_TAKING_STAIRS) && mon->place(true))
diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc
index a2a53951d6..05229ea6fa 100644
--- a/crawl-ref/source/mutation.cc
+++ b/crawl-ref/source/mutation.cc
@@ -1737,8 +1737,8 @@ bool mutate(mutation_type which_mutation, bool failMsg, bool force_mutation,
// except for demonspawn (or other permamutations) in lichform -- haranp
if (rotting && !demonspawn)
{
- if (!wearing_amulet(AMU_RESIST_MUTATION) ? !one_chance_in(3)
- : one_chance_in(10))
+ if (wearing_amulet(AMU_RESIST_MUTATION) ? one_chance_in(10)
+ : !one_chance_in(3))
{
mpr( "Your body decomposes!", MSGCH_MUTATION );
diff --git a/crawl-ref/source/randart.cc b/crawl-ref/source/randart.cc
index 6ed9069317..c17cf49a02 100644
--- a/crawl-ref/source/randart.cc
+++ b/crawl-ref/source/randart.cc
@@ -793,8 +793,8 @@ void static _get_randart_properties(const item_def &item,
}
}
- if (random2(15) >= power_level && aclass != OBJ_WEAPONS &&
- (aclass != OBJ_JEWELLERY || atype != RING_SLAYING))
+ if (random2(15) >= power_level && aclass != OBJ_WEAPONS
+ && (aclass != OBJ_JEWELLERY || atype != RING_SLAYING))
{
// Weapons and rings of slaying can't get these
if (one_chance_in(4 + power_level)) // to-hit
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 8772f79264..880ba5d0b2 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -773,7 +773,7 @@ static void _give_nemelex_gift()
bool is_good_follower(const monsters* mon)
{
return (mon->alive() && !mons_is_evil_or_unholy(mon)
- && mons_friendly(mon));
+ && mons_friendly(mon));
}
bool is_orcish_follower(const monsters* mon)
@@ -1054,6 +1054,7 @@ static bool _beogh_blessing_priesthood(monsters* mon)
// function normally used when going up an experience level.
// This is a hack, but there seems to be no better way for now.
mon->upgrade_type(priest_type, true, true);
+ give_unique_monster_name(mon);
return true;
}
@@ -1065,7 +1066,8 @@ static bool _beogh_blessing_priesthood(monsters* mon)
// one, bless a random follower within sight of the player, if any.
bool bless_follower(monsters* follower,
god_type god,
- bool (*suitable)(const monsters* mon))
+ bool (*suitable)(const monsters* mon),
+ bool force)
{
monsters *mon = NULL;
@@ -1074,11 +1076,13 @@ bool bless_follower(monsters* follower,
std::string result;
int chance = random2(20);
+ if (force)
+ chance = coinflip();
bool is_near = false;
// If a follower was specified, and it's suitable, pick it.
- if (follower && suitable(follower))
+ if (follower && (force || suitable(follower)))
mon = follower;
// Otherwise, pick a random follower within sight of the player.
else
@@ -1107,7 +1111,7 @@ bool bless_follower(monsters* follower,
{
pronoun = "";
blessed = "you";
- result = "reinforcement";
+ result = "reinforcement";
goto blessing_done;
}
break;
@@ -1143,6 +1147,8 @@ bool bless_follower(monsters* follower,
result = "holy attack power";
goto blessing_done;
}
+ else if (force)
+ mpr("Couldn't bless monster's weapon.");
}
else
{
@@ -1153,6 +1159,8 @@ bool bless_follower(monsters* follower,
result = "life defence";
goto blessing_done;
}
+ else if (force)
+ mpr("Couldn't bless monster's armour.");
}
break;
@@ -1163,6 +1171,8 @@ bool bless_follower(monsters* follower,
result = "priesthood";
goto blessing_done;
}
+ else if (force)
+ mpr("Couldn't promote monster to priesthood.");
break;
default:
@@ -1189,8 +1199,11 @@ bool bless_follower(monsters* follower,
if (affected)
{
result = "extra attack power";
+ give_unique_monster_name(mon);
goto blessing_done;
}
+ else if (force)
+ mpr("Couldn't enchant monster's weapon.");
}
else
{
@@ -1205,8 +1218,11 @@ bool bless_follower(monsters* follower,
if (affected)
{
result = "extra defence";
+ give_unique_monster_name(mon);
goto blessing_done;
}
+ else if (force)
+ mpr("Couldn't enchant monster's armour.");
}
}
@@ -1229,6 +1245,8 @@ bool bless_follower(monsters* follower,
result = "more time in this world";
else if (friendliness)
result = "friendliness";
+ else if (force)
+ mpr("Couldn't increase monster's friendliness or time.");
if (more_time || friendliness)
break;
@@ -1258,8 +1276,12 @@ bool bless_follower(monsters* follower,
else if (vigour)
result = "extra vigour";
else
- return false;
+ {
+ if (force)
+ mpr("Couldn't heal monster.");
+ return false;
+ }
break;
}
@@ -1268,8 +1290,13 @@ bool bless_follower(monsters* follower,
}
blessing_done:
- snprintf(info, INFO_SIZE, " blesses %s%s with %s.",
- pronoun.c_str(), blessed.c_str(), result.c_str());
+ std::string whom = get_unique_monster_name(mon);
+ if (whom.empty())
+ whom = pronoun + blessed;
+
+ snprintf(info, INFO_SIZE, " blesses %s with %s.",
+ whom.c_str(), result.c_str());
+
simple_god_message(info);
#ifndef USE_TILE
diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h
index 29cf763615..16d5e5f7fc 100644
--- a/crawl-ref/source/religion.h
+++ b/crawl-ref/source/religion.h
@@ -80,7 +80,8 @@ bool is_orcish_follower(const monsters* mon);
bool is_follower(const monsters* mon);
bool bless_follower(monsters* follower = NULL,
god_type god = you.religion,
- bool (*suitable)(const monsters* mon) = is_follower);
+ bool (*suitable)(const monsters* mon) = is_follower,
+ bool force = false);
bool god_hates_attacking_friend(god_type god, const actor *fr);