diff options
-rw-r--r-- | crawl-ref/source/debug.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/decks.cc | 20 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 11 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 200 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/monplace.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 46 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.h | 24 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 58 | ||||
-rw-r--r-- | crawl-ref/source/religion.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/stuff.h | 5 | ||||
-rw-r--r-- | crawl-ref/source/tags.cc | 13 | ||||
-rw-r--r-- | crawl-ref/source/tags.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/xom.cc | 16 |
14 files changed, 189 insertions, 220 deletions
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index cbc1d14429..0aa7ca040b 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -3563,7 +3563,7 @@ void debug_apply_monster_blessing(monsters* mon) else god = GOD_SHINING_ONE; - if (!bless_follower(monster_index(mon), god, _force_suitable, true)) + if (!bless_follower(mon, god, _force_suitable, true)) mprf("%s won't bless this monster for you!", god_name(god).c_str()); } #endif diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc index c64eca497e..14c67f1a8e 100644 --- a/crawl-ref/source/decks.cc +++ b/crawl-ref/source/decks.cc @@ -1346,24 +1346,24 @@ static void _swap_monster_card(int power, deck_rarity_type rarity) // Swap between you and another monster. // Don't choose yourself unless there are no other monsters // nearby. - const int mon_to_swap = choose_random_nearby_monster(0); - if ( mon_to_swap == NON_MONSTER ) + monsters *mon_to_swap = choose_random_nearby_monster(0); + if ( !mon_to_swap ) { mpr("You spin around."); } else { - monsters& mon = menv[mon_to_swap]; - const coord_def newpos = menv[mon_to_swap].pos(); + monsters& mon(*mon_to_swap); + const coord_def newpos = mon.pos(); // pick the monster up - mgrd[mon.x][mon.y] = NON_MONSTER; + mgrd(newpos) = NON_MONSTER; mon.x = you.x_pos; mon.y = you.y_pos; // plunk it down - mgrd[mon.x][mon.y] = mon_to_swap; + mgrd(mon.pos()) = monster_index(mon_to_swap); // move you to its previous location you.moveto(newpos); @@ -1403,19 +1403,19 @@ static void _damnation_card(int power, deck_rarity_type rarity) for ( int i = 0; i < 1 + extra_targets; ++i ) { // pick a random monster nearby to banish (or yourself) - const int mon_to_banish = choose_random_nearby_monster(1); + monsters *mon_to_banish = choose_random_nearby_monster(1); // bonus banishments only banish monsters - if ( i != 0 && mon_to_banish == NON_MONSTER ) + if ( i != 0 && !mon_to_banish ) continue; - if ( mon_to_banish == NON_MONSTER ) // banish yourself! + if ( !mon_to_banish ) // banish yourself! { banished(DNGN_ENTER_ABYSS, "drawing a card"); break; // don't banish anything else } else - menv[mon_to_banish].banish(); + mon_to_banish->banish(); } } diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 852c35d2e5..71af54fc6c 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -1010,8 +1010,11 @@ public: ~monsters(); monsters &operator = (const monsters &other); + void reset(); public: + std::string mname; + int type; int hit_points; int max_hit_points; @@ -1050,10 +1053,14 @@ public: // AI_SEE_MONSTER public: + // Returns true if the monster is named with a proper name, or is + // a player ghost. + bool is_named() const; + const monsterentry *find_monsterentry() const; + void init_experience(); void mark_summoned(int longevity, bool mark_items_summoned ); - bool has_action_energy() const; void check_redraw(const coord_def &oldpos) const; void apply_location_effects(); @@ -1098,7 +1105,6 @@ public: void ghost_init(); void pandemon_init(); void destroy_inventory(); - void reset(); void load_spells(mon_spellbook_type spellbook); actor *get_foe() const; @@ -1262,7 +1268,6 @@ private: coord_def &chosen, int &nvalid) const; bool has_spell_of_type(unsigned) const; - const monsterentry *find_monsterentry() const; }; struct cloud_struct diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 3f52027037..3982b29782 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -472,8 +472,7 @@ bool invalid_monster_class(int mclass) bool invalid_monster_index(int i) { - return (i < 0 - || i >= MAX_MONSTERS); + return (i < 0 || i >= MAX_MONSTERS); } bool mons_is_statue(int mc) @@ -1373,6 +1372,7 @@ void define_monster(monsters &mons) int col = mons_class_colour(mons.type); mon_spellbook_type spells = MST_NO_SPELLS; + mons.mname.clear(); hd = m->hpdice[0]; // misc @@ -1629,6 +1629,11 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, if (mon.type == MONS_PANDEMONIUM_DEMON) return mon.ghost->name; + // If the monster has an explicit name, return that, handling it like + // a unique's name. + if (!mon.mname.empty()) + return mon.mname; + std::string result; // Start building the name string. @@ -1750,20 +1755,34 @@ std::string mons_type_name(int type, description_level_type desc ) return result; } +// XXX: unique as in "proper name", not unique as in "name not used elsewhere"? +static std::string _get_unique_monster_name(const monsters *mon) +{ + const monsterentry *me = mon->find_monsterentry(); + if (!me) + return (""); + + std::string name = getRandNameString(me->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; +} + // 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 orcs_only) { // already has a unique name - if (mon->number > 0 && mon->number != MONS_PROGRAM_BUG) - return false; - - // already have a name - if (mons_is_unique(mon->type) || mon->type == MONS_PLAYER_GHOST - || mon->type == MONS_PANDEMONIUM_DEMON) - { - return false; - } + if (mon->is_named()) + return (false); // Since this is called from the various divine blessing routines, // don't bless non-orcs, and normally don't bless plain orcs, either. @@ -1775,79 +1794,11 @@ bool give_unique_monster_name(monsters *mon, bool orcs_only) return false; } } - else - { - // 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; - } - } - - // 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 (mon->type == MONS_PLAYER_GHOST) - return mon->ghost->name + "'s ghost"; - - if (mon->type == MONS_PANDEMONIUM_DEMON) - return mon->ghost->name; - - if (mons_is_unique(mon->type)) - return get_monster_data(mon->type)->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; + mon->mname = _get_unique_monster_name(mon); + return (mon->is_named()); } -/* ********************* END PUBLIC FUNCTIONS ********************* */ - // see mons_init for initialization of mon_entry array. monsterentry *get_monster_data(int p_monsterid) { @@ -2612,8 +2563,39 @@ monsters &monsters::operator = (const monsters &mon) return (*this); } +void monsters::reset() +{ + destroy_inventory(); + + mname.clear(); + enchantments.clear(); + 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; + speed_increment = 0; + attitude = ATT_HOSTILE; + behaviour = BEH_SLEEP; + foe = MHITNOT; + number = 0; + + if (in_bounds(x, y)) + mgrd[x][y] = NON_MONSTER; + + x = y = 0; + ghost.reset(NULL); +} + void monsters::init_with(const monsters &mon) { + mname = mon.mname; type = mon.type; hit_points = mon.hit_points; max_hit_points = mon.max_hit_points; @@ -3914,14 +3896,13 @@ item_def *monsters::shield() return (mslot_item(MSLOT_SHIELD)); } -std::string monsters::name(description_level_type desc) const +bool monsters::is_named() const { - std::string monnam = ""; - if (player_monster_visible(this)) - monnam = get_unique_monster_name(this); - if (!monnam.empty()) - return monnam; + return (!mname.empty() || mons_is_unique(type)); +} +std::string monsters::name(description_level_type desc) const +{ return this->name(desc, false); } @@ -3933,8 +3914,8 @@ std::string monsters::name(description_level_type desc, bool force_vis) const if (possessive) desc = DESC_NOCAP_THE; - std::string mname = _str_monam(*this, desc, force_vis); - return (possessive? apostrophise(mname) : mname); + std::string monnam = _str_monam(*this, desc, force_vis); + return (possessive? apostrophise(monnam) : monnam); } std::string monsters::pronoun(pronoun_type pro) const @@ -4305,6 +4286,7 @@ void monsters::set_ghost(const ghost_demon &g) TileGhostInit(g); #endif ghost.reset( new ghost_demon(g) ); + mname = ghost->name; } void monsters::pandemon_init() @@ -4446,35 +4428,6 @@ void monsters::destroy_inventory() } } -void monsters::reset() -{ - destroy_inventory(); - - enchantments.clear(); - 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; - speed_increment = 0; - attitude = ATT_HOSTILE; - behaviour = BEH_SLEEP; - foe = MHITNOT; - number = 0; - - if (in_bounds(x, y)) - mgrd[x][y] = NON_MONSTER; - - x = y = 0; - ghost.reset(NULL); -} - bool monsters::needs_transit() const { return ((mons_is_unique(type) @@ -5809,17 +5762,17 @@ void monsters::react_to_damage(int damage) if (needs_message) { - const std::string mname = name(DESC_CAP_THE); - mprf("%s shudders%s.", mname.c_str(), + const std::string monnam = name(DESC_CAP_THE); + mprf("%s shudders%s.", monnam.c_str(), spawned >= 5 ? " alarmingly" : spawned >= 3 ? " violently" : spawned > 1 ? " vigorously" : ""); if (spawned == 1) - mprf("%s spits out another jelly.", mname.c_str()); + mprf("%s spits out another jelly.", monnam.c_str()); else { mprf("%s spits out %s more jellies.", - mname.c_str(), + monnam.c_str(), number_in_words(spawned).c_str()); } } @@ -6080,7 +6033,8 @@ std::string do_mon_str_replacements(const std::string &in_msg, std::string msg = in_msg; description_level_type nocap = DESC_NOCAP_THE, cap = DESC_CAP_THE; - std::string name = get_unique_monster_name(monster); + std::string name = + monster->is_named()? monster->name(DESC_CAP_THE) : ""; if (!name.empty() && player_monster_visible(monster)) { msg = replace_all(msg, "@the_something@", name); diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index 34089fd724..fc1715ba8b 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -387,7 +387,6 @@ monsters *monster_at(const coord_def &pos); std::string mons_type_name(int type, description_level_type desc); bool give_unique_monster_name(monsters *mon, bool orcs_only = true); -std::string get_unique_monster_name(const monsters *mon); // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 9f98a18fef..c74d4cdb2a 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -716,11 +716,8 @@ static int place_monster_aux( int mon_type, beh_type behaviour, int target, if (id == MAX_MONSTERS) return -1; - menv[id].inv.init(NON_ITEM); - // scrap monster enchantments - menv[id].enchantments.clear(); - menv[id].ench_countdown = 0; - + menv[id].reset(); + // setup habitat and placement // If the space is occupied, try some neighbouring square instead. if (first_band_member && mgrd[px][py] == NON_MONSTER diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index a75a471916..7d73b0cdc4 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -418,7 +418,7 @@ static void _give_monster_experience( monsters *victim, || you.religion == GOD_BEOGH && random2(you.piety) >= piety_breakpoint(2)) { - bless_follower(killer_index); + bless_follower(mon); } } } @@ -1121,8 +1121,11 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) monsters *mon = &menv[i]; // Randomly bless the follower who killed. - if (!one_chance_in(3) && bless_follower(i)) + if (!one_chance_in(3) && mon->alive() + && bless_follower(mon)) + { break; + } if (mon->alive() && mon->hit_points < mon->max_hit_points) { @@ -1140,7 +1143,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) && !one_chance_in(3) && !invalid_monster_index(i)) { - bless_follower(i); + bless_follower(&menv[i]); } } @@ -2604,22 +2607,21 @@ bool choose_any_monster(const monsters* mon) // for the type of monster wanted. // If prefer_named is true, named monsters (including uniques) are twice as // likely to get chosen compared with non-named ones. -int choose_random_nearby_monster(int weight, - bool (*suitable)(const monsters* mon), - bool in_sight, bool prefer_named) +monsters *choose_random_nearby_monster(int weight, + bool (*suitable)(const monsters* mon), + bool in_sight, bool prefer_named) { return choose_random_monster_on_level(weight, suitable, in_sight, true, prefer_named); } -int choose_random_monster_on_level(int weight, - bool (*suitable)(const monsters* mon), - bool in_sight, bool near_by, - bool prefer_named) +monsters *choose_random_monster_on_level(int weight, + bool (*suitable)(const monsters* mon), + bool in_sight, bool near_by, + bool prefer_named) { + monsters *chosen = NULL; int mons_count = weight; - int result = NON_MONSTER; - int mon; int xstart = 0, ystart = 0; int xend = GXM, yend = GYM; @@ -2642,23 +2644,27 @@ int choose_random_monster_on_level(int weight, for ( int x = xstart; x < xend; ++x ) if ( mgrd[x][y] != NON_MONSTER && (!in_sight || see_grid(x,y)) ) { - mon = mgrd[x][y]; - if (suitable(&menv[mon])) + monsters *mon = &menv[mgrd[x][y]]; + if (suitable(mon)) { - if (prefer_named - && !(get_unique_monster_name(&menv[mon]).empty())) + // FIXME: if the intent is to favour monsters + // named by $DEITY, we should set a flag on the + // monster (something like MF_DEITY_PREFERRED) and + // use that instead of checking the name, given + // that other monsters can also have names. + if (prefer_named && mon->is_named()) { mons_count += 2; // named monsters have doubled chances if (random2(mons_count) < 2) - result = mon; + chosen = mon; } else if (one_chance_in(++mons_count)) - result = mon; + chosen = mon; } } - - return result; + + return chosen; } // note that this function *completely* blocks messaging for monsters diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h index 96f16883d1..5fc1a8a25a 100644 --- a/crawl-ref/source/monstuff.h +++ b/crawl-ref/source/monstuff.h @@ -123,17 +123,19 @@ bool simple_monster_message(const monsters *monster, const char *event, description_level_type descrip = DESC_CAP_THE); bool choose_any_monster(const monsters* mon); -int choose_random_nearby_monster(int weight, - bool (*suitable)(const monsters* mon) = - choose_any_monster, - bool in_sight = true, - bool prefer_named = false); - -int choose_random_monster_on_level(int weight, - bool (*suitable)(const monsters* mon) = - choose_any_monster, - bool in_sight = true, bool near_by = false, - bool prefer_named = false); +monsters *choose_random_nearby_monster( + int weight, + bool (*suitable)(const monsters* mon) = + choose_any_monster, + bool in_sight = true, + bool prefer_named = false); + +monsters *choose_random_monster_on_level( + int weight, + bool (*suitable)(const monsters* mon) = + choose_any_monster, + bool in_sight = true, bool near_by = false, + bool prefer_named = false); /* *********************************************************************** * called from: acr diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 3f372efab0..3cfa93071e 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -1092,18 +1092,17 @@ static bool _beogh_blessing_priesthood(monsters* mon) // one, bless a random follower within sight of the player, if any, or, // with decreasing chances, any follower on the level. // Blessing can be enforced with a wizard mode command. -bool bless_follower(int follower, +bool bless_follower(monsters *follower, god_type god, bool (*suitable)(const monsters* mon), bool force) { int chance = (force ? coinflip() : random2(20)); - monsters *mon = NULL; std::string result; // If a follower was specified, and it's suitable, pick it. // Otherwise, pick a random follower within sight of the player. - if (follower == -1 || (!force && !suitable(&menv[follower]))) + if (!follower || (!force && !suitable(follower))) { if (god != GOD_BEOGH) return false; @@ -1114,7 +1113,7 @@ bool bless_follower(int follower, // Choose a random follower in LOS, preferably a named one (10% chance). follower = choose_random_nearby_monster(0, suitable, true, true); - if (follower == NON_MONSTER) + if (!follower) { if (coinflip()) return false; @@ -1122,7 +1121,7 @@ bool bless_follower(int follower, // Try again, without the LOS restriction (5% chance). follower = choose_random_nearby_monster(0, suitable, false, true); - if (follower == NON_MONSTER) + if (!follower) { if (coinflip()) return false; @@ -1131,7 +1130,7 @@ bool bless_follower(int follower, follower = choose_random_monster_on_level(0, suitable, false, false, true); - if (follower == NON_MONSTER) + if (!follower) { // If no follower was found, attempt to send // reinforcement. @@ -1153,10 +1152,7 @@ bool bless_follower(int follower, } } } - ASSERT(follower != -1 && follower != NON_MONSTER); - - // Else, apply blessing to chosen follower. - mon = &menv[follower]; + ASSERT(follower); if (chance == 0) // 5% chance of holy branding, or priesthood { @@ -1167,7 +1163,7 @@ bool bless_follower(int follower, { // Brand a monster's weapon with holy wrath, if // possible. - if (_tso_blessing_holy_wpn(mon)) + if (_tso_blessing_holy_wpn(follower)) { result = "holy attack power"; goto blessing_done; @@ -1179,7 +1175,7 @@ bool bless_follower(int follower, { // Brand a monster's armour with positive energy, if // possible. - if (_tso_blessing_holy_arm(mon)) + if (_tso_blessing_holy_arm(follower)) { result = "life defence"; goto blessing_done; @@ -1191,7 +1187,7 @@ bool bless_follower(int follower, case GOD_BEOGH: // Turn a monster into a priestly monster, if possible. - if (_beogh_blessing_priesthood(mon)) + if (_beogh_blessing_priesthood(follower)) { result = "priesthood"; goto blessing_done; @@ -1214,18 +1210,18 @@ bool bless_follower(int follower, if (coinflip()) { - affected = _blessing_wpn(mon); + affected = _blessing_wpn(follower); if (!affected || coinflip()) { - if (_blessing_wpn(mon)) + if (_blessing_wpn(follower)) affected = true; } if (affected) { result = "extra attack power"; - give_unique_monster_name(mon); + give_unique_monster_name(follower); goto blessing_done; } else if (force) @@ -1233,18 +1229,18 @@ bool bless_follower(int follower, } else { - affected = _blessing_AC(mon); + affected = _blessing_AC(follower); if (!affected || coinflip()) { - if (_blessing_AC(mon)) + if (_blessing_AC(follower)) affected = true; } if (affected) { result = "extra defence"; - give_unique_monster_name(mon); + give_unique_monster_name(follower); goto blessing_done; } else if (force) @@ -1261,11 +1257,11 @@ bool bless_follower(int follower, // Extend a monster's stay if it's abjurable, optionally // making it friendly if it's charmed. If neither is // possible, deliberately fall through. - bool more_time = _tso_blessing_extend_stay(mon); + bool more_time = _tso_blessing_extend_stay(follower); bool friendliness = false; if (!more_time || coinflip()) - friendliness = _tso_blessing_friendliness(mon); + friendliness = _tso_blessing_friendliness(follower); if (more_time && friendliness) result = "friendliness and more time in this world"; @@ -1288,7 +1284,7 @@ bool bless_follower(int follower, // possible. if (coinflip()) { - if (_blessing_balms(mon)) + if (_blessing_balms(follower)) { result = "divine balms"; goto blessing_done; @@ -1297,12 +1293,12 @@ bool bless_follower(int follower, mpr("Couldn't apply balms."); } - bool healing = _blessing_healing(mon, false); + bool healing = _blessing_healing(follower, false); bool vigour = false; // Maybe give an extra hit point. if (!healing || coinflip()) - vigour = _blessing_healing(mon, true); + vigour = _blessing_healing(follower, true); if (healing && vigour) result = "healing and extra vigour"; @@ -1329,18 +1325,19 @@ blessing_done: bool see_follower = false; std::string whom = ""; - if (follower == NON_MONSTER) + if (!follower) whom = "you"; else { - if (mons_near(mon) && player_monster_visible(mon)) + if (mons_near(follower) && player_monster_visible(follower)) see_follower = true; if (see_follower) { - whom = get_unique_monster_name(mon); - if (whom.empty()) - whom = "your " + mon->name(DESC_PLAIN); + if (follower->is_named()) + whom = follower->name(DESC_PLAIN); + else + whom = "your " + follower->name(DESC_PLAIN); } else // cannot see who was blessed whom = "a follower"; @@ -1355,7 +1352,7 @@ blessing_done: if (see_follower) { unsigned char old_flash_colour = you.flash_colour; - coord_def c(mon->x, mon->y); + coord_def c(follower->pos()); you.flash_colour = god_colour(god); view_update_at(c); @@ -1365,6 +1362,7 @@ blessing_done: you.flash_colour = old_flash_colour; view_update_at(c); + update_screen(); } #endif diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h index 7e972edeef..e870841980 100644 --- a/crawl-ref/source/religion.h +++ b/crawl-ref/source/religion.h @@ -78,7 +78,7 @@ bool tso_stab_safe_monster(const actor *act); bool is_good_follower(const monsters* mon); bool is_orcish_follower(const monsters* mon); bool is_follower(const monsters* mon); -bool bless_follower(int follower = -1, +bool bless_follower(monsters *follower = NULL, god_type god = you.religion, bool (*suitable)(const monsters* mon) = is_follower, bool force = false); diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h index d7b59c6cb4..8d07f41206 100644 --- a/crawl-ref/source/stuff.h +++ b/crawl-ref/source/stuff.h @@ -162,8 +162,9 @@ void zap_los_monsters(); class rng_save_excursion { public: - rng_save_excursion() { push_rng_state(); } - ~rng_save_excursion() { pop_rng_state(); } + rng_save_excursion(long seed) { push_rng_state(); seed_rng(seed); } + rng_save_excursion() { push_rng_state(); } + ~rng_save_excursion() { pop_rng_state(); } }; template<typename Iterator> diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 7cad040f15..92b4c994ee 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -99,6 +99,9 @@ extern std::map<level_id, std::string> level_annotations; // temp file pairs used for file level cleanup FixedArray < bool, MAX_LEVELS, NUM_BRANCHES > tmp_file_pairs; +// The minor version for the tag currently being read. +static int _tag_minor_version = -1; + // Reads input in network byte order, from a file or buffer. unsigned char reader::readByte() { @@ -706,6 +709,7 @@ tag_type tag_read(FILE *fp, char minorVersion) return TAG_NO_TAG; } + unwind_var<int> tag_minor_version(_tag_minor_version, minorVersion); // ok, we have data now. reader th(buf); switch (tag_id) @@ -790,7 +794,7 @@ void tag_set_expected(char tags[], int fileType) switch(fileType) { case TAGTYPE_PLAYER: - if (i >= TAG_YOU && i <= TAG_YOU_DUNGEON + if ((i >= TAG_YOU && i <= TAG_YOU_DUNGEON) || i == TAG_LOST_MONSTERS) { tags[i] = 1; @@ -1580,7 +1584,6 @@ static void tag_read_you_dungeon(reader &th) static void tag_read_lost_monsters(reader &th, int minorVersion) { the_lost_ones.clear(); - unmarshallMap(th, the_lost_ones, unmarshall_level_id, unmarshall_follower_list); } @@ -1755,6 +1758,7 @@ static mon_enchant unmarshall_mon_enchant(reader &th) static void marshall_monster(writer &th, const monsters &m) { + marshallString(th, m.mname); marshallByte(th, m.ac); marshallByte(th, m.ev); marshallByte(th, m.hit_dice); @@ -2011,6 +2015,11 @@ static void tag_read_level_items(reader &th, char minorVersion) static void unmarshall_monster(reader &th, monsters &m) { + m.reset(); + + if (_tag_minor_version >= TAG_MINOR_MONNAM) + m.mname = unmarshallString(th, 100); + m.ac = unmarshallByte(th); m.ev = unmarshallByte(th); m.hit_dice = unmarshallByte(th); diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h index ff10c242e3..b7ff700e69 100644 --- a/crawl-ref/source/tags.h +++ b/crawl-ref/source/tags.h @@ -47,12 +47,14 @@ enum tag_major_version TAG_MAJOR_VERSION = 5 }; +// Minor version will be reset to zero when major version changes. enum tag_minor_version { TAG_MINOR_PIETY = 2, // Added piety_hysteresis TAG_MINOR_QUIVER = 3, // Added quiver TAG_MINOR_MAPMARK = 4, // Added sizes to map markers - TAG_MINOR_VERSION = 4 // Current version + TAG_MINOR_MONNAM = 5, // Monsters get individual names + TAG_MINOR_VERSION = 5 // Current version }; diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc index c6dd4be7c2..617517fd7e 100644 --- a/crawl-ref/source/xom.cc +++ b/crawl-ref/source/xom.cc @@ -622,15 +622,13 @@ static bool xom_is_good(int sever) if (!there_are_monsters_nearby()) goto try_again; - int monster = choose_random_nearby_monster(0, - choose_mutatable_monster); + monsters *mon = + choose_random_nearby_monster(0, choose_mutatable_monster); - if (monster != NON_MONSTER) + if (mon) { god_speaks(GOD_XOM, _get_xom_speech("good monster polymorph")); - monsters* mon = &menv[monster]; - if (mons_wont_attack(mon)) monster_polymorph(mon, RANDOM_MONSTER, PPT_MORE); else @@ -807,15 +805,13 @@ static bool xom_is_bad(int sever) if (!there_are_monsters_nearby()) goto try_again; - int monster = choose_random_nearby_monster(0, - choose_mutatable_monster); + monsters *mon = + choose_random_nearby_monster(0, choose_mutatable_monster); - if (monster != NON_MONSTER) + if (mon) { god_speaks(GOD_XOM, _get_xom_speech("bad monster polymorph")); - monsters* mon = &menv[monster]; - if (mons_wont_attack(mon)) monster_polymorph(mon, RANDOM_MONSTER, PPT_LESS); else |