From 904a64bbcff41f7ecde8de133ddf68eeb2a8959f Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Thu, 24 Apr 2008 09:35:03 +0000 Subject: * 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 --- crawl-ref/source/dat/database/randname.txt | 90 +++++++++++++ crawl-ref/source/debug.cc | 35 +++++- crawl-ref/source/debug.h | 1 + crawl-ref/source/describe.cc | 6 +- crawl-ref/source/directn.cc | 22 +++- crawl-ref/source/enum.h | 27 ++-- crawl-ref/source/mon-util.cc | 195 +++++++++++++++++++++++------ crawl-ref/source/mon-util.h | 17 +-- crawl-ref/source/monstuff.cc | 18 +-- crawl-ref/source/mtransit.cc | 3 +- crawl-ref/source/mutation.cc | 4 +- crawl-ref/source/randart.cc | 4 +- crawl-ref/source/religion.cc | 41 ++++-- crawl-ref/source/religion.h | 3 +- 14 files changed, 381 insertions(+), 85 deletions(-) (limited to 'crawl-ref/source') 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); @@ -3529,6 +3532,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) { 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); -- cgit v1.2.3-54-g00ecf