diff options
-rw-r--r-- | crawl-ref/docs/crawl_manual.txt | 5 | ||||
-rw-r--r-- | crawl-ref/docs/options_guide.txt | 24 | ||||
-rw-r--r-- | crawl-ref/init.txt | 1 | ||||
-rw-r--r-- | crawl-ref/source/acr.cc | 33 | ||||
-rw-r--r-- | crawl-ref/source/command.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/dat/database/monspeak.txt | 22 | ||||
-rw-r--r-- | crawl-ref/source/effects.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/food.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 17 | ||||
-rw-r--r-- | crawl-ref/source/items.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 31 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 16 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 30 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 178 |
17 files changed, 217 insertions, 163 deletions
diff --git a/crawl-ref/docs/crawl_manual.txt b/crawl-ref/docs/crawl_manual.txt index 4160e9d31b..6ae82b083f 100644 --- a/crawl-ref/docs/crawl_manual.txt +++ b/crawl-ref/docs/crawl_manual.txt @@ -2354,6 +2354,9 @@ Other game-playing commands: Ctrl-A Toggle autopickup. Note that encounters with invisible monsters always turns autopickup off. You need to switch it on with Ctrl-A afterwards. + Ctrl-T Toggle your allies' pickup behaviour between three + settings: don't pick up anything, only pick up + items dropped by allies, pick up anything. ` Re-do previous command 0 Repeat next command a given number of times @@ -2502,7 +2505,7 @@ work, with the exception of Space (which fires). key) using the option target_unshifted_dirs. Note that target_unshifted_dirs is mutually exclusive with default_target. - + Shortcuts in lists (like multidrop): ------------------------------------ When dropping (with the drop_mode=multi option), the drop menu accepts diff --git a/crawl-ref/docs/options_guide.txt b/crawl-ref/docs/options_guide.txt index d5e940a222..6d5356f477 100644 --- a/crawl-ref/docs/options_guide.txt +++ b/crawl-ref/docs/options_guide.txt @@ -24,7 +24,8 @@ The contents of this text are: 4-a Dropping and Picking up. autopickup, autopickup_exceptions, default_autopickup, autopickup_no_burden, pickup_thrown, pickup_dropped, - assign_item_slot, drop_mode, pickup_mode, drop_filter + assign_item_slot, drop_mode, pickup_mode, drop_filter, + default_friendly_pickup 4-b Targeting. target_zero_exp, target_oos, target_los_first, default_target, target_unshifted_dirs @@ -425,6 +426,27 @@ drop_filter = <regex> set/clear selection of items that match the filter expression(s). +default_friendly_pickup = (none | friend | all) + Using an in-game toggle, you can control what types of items + your allies will pick up: + none = They won't pick up anything at all. + (This is the old friendly pick up behaviour.) + friend = They will pick up anything they or another ally + dropped, e.g. if another ally dies. + (This is the default value.) + all = They will pick up anything they want to have. + (This is how it works for hostile monsters.) + + This option controls which is the default setting for this toggle + when you start or reload a game, or when you enter a level for + the first time. + + Note that monsters have their own reasonings for which items they + may need, and when they feel safe enough to pick them up. Except + for "none", these options won't let you override these. + Also, friendly jellies won't ever eat any items, regardless of this + option. + 4-b Targeting. ------------------- diff --git a/crawl-ref/init.txt b/crawl-ref/init.txt index 0876d07a87..2a34860c73 100644 --- a/crawl-ref/init.txt +++ b/crawl-ref/init.txt @@ -101,6 +101,7 @@ lua_file = lua/pickup.lua # drop_mode = (multi | single) # pickup_mode = (single | multi | auto:5) # drop_filter = skeleton, rotting, corpse +# default_friendly_pickup = friend ##### 4-b Targetting ############################ # diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 1df013c7e2..48aff3f09b 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -1248,6 +1248,7 @@ static bool _cmd_is_repeatable(command_type cmd, bool is_again = false) // Miscellaneous non-repeatable commands. case CMD_TOGGLE_AUTOPICKUP: + case CMD_TOGGLE_FRIENDLY_PICKUP: case CMD_ADJUST_INVENTORY: case CMD_REPLAY_MESSAGES: case CMD_REDRAW_SCREEN: @@ -2014,6 +2015,25 @@ void process_command( command_type cmd ) _toggle_flag( &Options.autoprayer_on, "Autoprayer" ); break; + case CMD_TOGGLE_FRIENDLY_PICKUP: + // Toggle pickup mode for friendlies. + if (Options.friendly_pickup == -1) + { + Options.friendly_pickup = 0; + mpr("Your allies may now only pick up items dropped by allies."); + } + else if (Options.friendly_pickup == 0) + { + Options.friendly_pickup = 1; + mpr("Your allies may now pick up anything they need."); + } + else + { + Options.friendly_pickup = -1; + mpr("Your allies are now forbidden to pick up anything at all."); + } + break; + case CMD_MAKE_NOTE: make_user_note(); break; @@ -2831,8 +2851,7 @@ static void _decrement_durations() if (you.berserk_penalty != NO_BERSERK_PENALTY) { const int chance = - 10 + - player_mutation_level(MUT_BERSERK) * 25 + 10 + player_mutation_level(MUT_BERSERK) * 25 + (wearing_amulet( AMU_RAGE ) ? 10 : 0) + (player_has_spell( SPELL_BERSERKER_RAGE ) ? 5 : 0); @@ -3521,7 +3540,7 @@ static command_type _keycode_to_command( keycode_type key ) #endif case CONTROL('R'): return CMD_REDRAW_SCREEN; case CONTROL('S'): return CMD_MARK_STASH; - case CONTROL('T'): return CMD_NO_CMD; + case CONTROL('T'): return CMD_TOGGLE_FRIENDLY_PICKUP; case CONTROL('V'): return CMD_TOGGLE_AUTOPRAYER; case CONTROL('W'): return CMD_FIX_WAYPOINT; case CONTROL('X'): return CMD_SAVE_GAME_NOW; @@ -3949,7 +3968,7 @@ static bool _initialise(void) init_properties(); burden_change(); - make_hungry(0,true); + make_hungry(0, true); you.redraw_strength = true; you.redraw_intelligence = true; @@ -3982,14 +4001,16 @@ static bool _initialise(void) update_turn_count(); trackers_init_new_level(false); - // Mark items in inventory as of unknown origin. - origin_set_inventory(origin_set_unknown); + Options.friendly_pickup = Options.default_friendly_pickup; // set vision radius to player's current vision setLOSRadius( you.current_vision ); if (newc) { + // Mark items in inventory as of unknown origin. + origin_set_inventory(origin_set_unknown); + // For a new game, wipe out monsters in LOS. zap_los_monsters(); } diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index b309425464..247cbfe1f4 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -1520,6 +1520,7 @@ static void add_formatted_keyhelp(column_composer &cols) cols.add_formatted( 0, + "\n" "<h>Item types (and common commands)\n" "<cyan>)</cyan> : hand weapons (<w>w</w>ield)\n" "<brown>(</brown> : missiles (<w>f</w>ire, <w>(</w> to cycle ammo)\n" @@ -1596,7 +1597,8 @@ static void add_formatted_keyhelp(column_composer &cols) "<w>x</w> : eXamine surroundings/targets\n" "<w>X</w> : eXamine level map\n" "<w>Ctrl-O</w> : show dungeon Overview\n" - "<w>Ctrl-A</w> : toggle auto-pickup\n", + "<w>Ctrl-A</w> : toggle auto-pickup\n" + "<w>Ctrl-T</w> : toggle ally pickup behaviour\n", true, true, cmdhelp_textfilter); cols.add_formatted( diff --git a/crawl-ref/source/dat/database/monspeak.txt b/crawl-ref/source/dat/database/monspeak.txt index 2f5d4d8887..73fb1ac48f 100644 --- a/crawl-ref/source/dat/database/monspeak.txt +++ b/crawl-ref/source/dat/database/monspeak.txt @@ -2112,12 +2112,18 @@ maim related beogh orc # hostile orcs shouldn't be too talkative -w:80 +w:60 __NONE -w:30 +w:1 @_generic_orc_speech_@ +w:5 +@_hostile_beogh_speech_@ + +%%%% +_hostile_beogh_speech_ + # unbelievers @The_monster@ @orc_says@, "I don't believe in Beogh!" @@ -2174,17 +2180,23 @@ VISUAL:@The_monster@ stares at you quizzically. friendly related beogh orc # As they'll be constantly around you, don't let them talk too much. -w:50 +w:30 __NONE # general friendly speech -w:30 +w:1 @default friendly humanoid@ -w:30 +w:1 @_generic_orc_speech_@ w:5 +@_friendly_beogh_speech_@ + +%%%% +_friendly_beogh_speech_ + +w:5 @The_monster@ @loudly_or_repeatedly@ @shouts@ encouragement@orc_modifier@ @The_monster@ @says_or_shouts@, "Beogh is great, and so is @player_name@!" diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 9a33e78076..6ffc7aa513 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -1947,8 +1947,8 @@ void yell(bool force) return; } - if (!targ.isValid || mgrd[targ.tx][targ.ty] == NON_MONSTER || - !player_monster_visible(&env.mons[mgrd[targ.tx][targ.ty]])) + if (!targ.isValid || mgrd[targ.tx][targ.ty] == NON_MONSTER + || !player_monster_visible(&env.mons[mgrd[targ.tx][targ.ty]])) { mpr("Yeah, whatever."); return; diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 0d44153e1d..d34f4c0b58 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -431,6 +431,7 @@ enum command_type CMD_GO_UPSTAIRS, CMD_GO_DOWNSTAIRS, CMD_TOGGLE_AUTOPICKUP, + CMD_TOGGLE_FRIENDLY_PICKUP, CMD_PICKUP, CMD_DROP, CMD_BUTCHER, diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 27ca15cc87..70ed81541a 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -1585,6 +1585,8 @@ public: bool autopickup_on; bool autoprayer_on; + int default_friendly_pickup; + int friendly_pickup; bool show_more_prompt; bool show_gold_turns; // Show gold and turns in HUD. diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc index e3028e7187..5a4dbebdac 100644 --- a/crawl-ref/source/food.cc +++ b/crawl-ref/source/food.cc @@ -78,7 +78,7 @@ void make_hungry( int hunger_amount, bool suppress_msg ) if (you.is_undead == US_UNDEAD) return; - if (hunger_amount == 0) + if (hunger_amount == 0 && !suppress_msg) return; #if DEBUG_DIAGNOSTICS diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index 074f8d3482..cdefa08af0 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -627,6 +627,8 @@ void game_options::reset_options() autopickup_on = true; autoprayer_on = false; + default_friendly_pickup = 0; // allies may only pickup items + friendly_pickup = 0; // dropped by allies show_more_prompt = true; show_gold_turns = false; @@ -1800,6 +1802,15 @@ void game_options::read_option_line(const std::string &str, bool runscript) else BOOL_OPTION(use_old_selection_order); else BOOL_OPTION_NAMED("default_autopickup", autopickup_on); else BOOL_OPTION_NAMED("default_autoprayer", autoprayer_on); + else if (key == "default_friendly_pickup") + { + if (field == "none") + friendly_pickup = -1; + else if (field == "all") + friendly_pickup = 1; + else if (field == "friend") + friendly_pickup = 0; + } else BOOL_OPTION(show_inventory_weights); else BOOL_OPTION(suppress_startup_errors); else BOOL_OPTION(clean_map); @@ -1961,7 +1972,7 @@ void game_options::read_option_line(const std::string &str, bool runscript) { set_fire_order(field, plus_equal); } - + BOOL_OPTION(random_pick); else BOOL_OPTION(remember_name); #ifndef SAVE_DIR_PATH @@ -2247,7 +2258,7 @@ void game_options::read_option_line(const std::string &str, bool runscript) } } } - + BOOL_OPTION(pickup_thrown); else BOOL_OPTION(pickup_dropped); #ifdef WIZARD @@ -2411,7 +2422,7 @@ void game_options::read_option_line(const std::string &str, bool runscript) } else BOOL_OPTION(explore_greedy); else BOOL_OPTION(explore_improved); - + BOOL_OPTION(trap_prompt); else if (key == "stash_tracking") { diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index f2c89cd3e6..66823ea7c1 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -931,10 +931,8 @@ void origin_acquired(item_def &item, int agent) void origin_set_inventory(void (*oset)(item_def &item)) { for (int i = 0; i < ENDOFPACK; ++i) - { if (is_valid_item(you.inv[i])) oset(you.inv[i]); - } } static int first_corpse_monnum(int x, int y) @@ -1582,6 +1580,8 @@ int move_item_to_player( int obj, int quant_got, bool quiet ) item.x = -1; item.y = -1; item.link = freeslot; + // remove "dropped by ally" flag + item.flags &= ~(ISFLAG_DROPPED_BY_ALLY); if (!item.slot) item.slot = index_to_letter(item.link); diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index c589ebc7ea..181dd8f2a3 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -154,7 +154,7 @@ void turn_corpse_into_chunks( item_def &item ) item.quantity = stepdown_value( item.quantity, 4, 4, 12, 12 ); if (you.species != SP_VAMPIRE) - item.flags &= ~(ISFLAG_THROWN | ISFLAG_DROPPED); + item.flags &= ~(ISFLAG_THROWN | ISFLAG_DROPPED); // happens after the corpse has been butchered if (monster_descriptor(mons_class, MDSC_LEAVES_HIDE) && !one_chance_in(3)) @@ -2013,21 +2013,13 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, dungeon_terrain_changed(you.pos(), DNGN_FLOOR); if (stair_find == DNGN_ENTER_LABYRINTH) - { you.level_type = LEVEL_LABYRINTH; - } else if (stair_find == DNGN_ENTER_ABYSS) - { you.level_type = LEVEL_ABYSS; - } else if (stair_find == DNGN_ENTER_PANDEMONIUM) - { you.level_type = LEVEL_PANDEMONIUM; - } else if (stair_find == DNGN_ENTER_PORTAL_VAULT) - { you.level_type = LEVEL_PORTAL_VAULT; - } // When going downstairs into a special level, delete any previous // instances of it @@ -2045,7 +2037,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, if (stair_find == DNGN_EXIT_ABYSS || stair_find == DNGN_EXIT_PANDEMONIUM) { mpr("You pass through the gate."); - if (!(you.wizard && crawl_state.is_replaying_keys())) + if (!you.wizard || !crawl_state.is_replaying_keys()) more(); } @@ -2139,15 +2131,16 @@ void down_stairs( int old_level, dungeon_feature_type force_stair, more(); } - const bool newlevel = - load(stair_taken, LOAD_ENTER_LEVEL, old_level_type, - old_level, old_where); + const bool newlevel = load(stair_taken, LOAD_ENTER_LEVEL, old_level_type, + old_level, old_where); set_entry_cause(entry_cause, old_level_type); entry_cause = you.entry_cause; if (newlevel) { + Options.friendly_pickup = Options.default_friendly_pickup; + switch(you.level_type) { case LEVEL_DUNGEON: @@ -2694,12 +2687,12 @@ int str_to_shoptype(const std::string &s) /* Decides whether autoprayer Right Now is a good idea. */ static bool should_autopray() { - if ( Options.autoprayer_on == false || - you.religion == GOD_NO_GOD || - you.religion == GOD_NEMELEX_XOBEH || - you.duration[DUR_PRAYER] || - grid_altar_god( grd[you.x_pos][you.y_pos] ) != GOD_NO_GOD || - !i_feel_safe() ) + if ( Options.autoprayer_on == false + || you.religion == GOD_NO_GOD + || you.religion == GOD_NEMELEX_XOBEH + || you.duration[DUR_PRAYER] + || grid_altar_god( grd[you.x_pos][you.y_pos] ) != GOD_NO_GOD + || !i_feel_safe() ) { return false; } diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index f5e8a8b66f..578ef73e35 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -3691,17 +3691,23 @@ bool monsters::pickup_item(item_def &item, int near, bool force) return false; } - // Friendlies may only pick up stuff dropped by (other) allies. - if (mons_friendly(this) - && !testbits(item.flags, ISFLAG_DROPPED_BY_ALLY)) + // Depending on the friendly pickup toggle, your allies may not pick + // up anything, or only stuff dropped by (other) allies. + if (mons_friendly(this)) { - return false; + if (Options.friendly_pickup < 0 + || Options.friendly_pickup == 0 + && !testbits(item.flags, ISFLAG_DROPPED_BY_ALLY)) + { + return false; + } } - // These are not important enough for pickup when seeking, fleeing etc. const int itype = item.base_type; if (!wandering) { + // These are not important enough for pickup when + // seeking, fleeing etc. if (itype == OBJ_ARMOUR || itype == OBJ_CORPSES || itype == OBJ_MISCELLANY || itype == OBJ_GOLD) { diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 0b44a9eb7b..63b14af650 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -2596,16 +2596,34 @@ int 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) +{ int mons_count = weight; int result = NON_MONSTER; int mon; - int ystart = you.y_pos - 9, xstart = you.x_pos - 9; - int yend = you.y_pos + 9, xend = you.x_pos + 9; - if ( xstart < 0 ) xstart = 0; - if ( ystart < 0 ) ystart = 0; - if ( xend >= GXM ) xend = GXM; - if ( yend >= GYM ) yend = GYM; + int xstart = 0, ystart = 0; + int xend = GXM, yend = GYM; + + if (near_by) + { + xstart = you.x_pos - 9; + ystart = you.y_pos - 9; + xend = you.x_pos + 9; + yend = you.y_pos + 9; + + if ( xstart < 0 ) xstart = 0; + if ( ystart < 0 ) ystart = 0; + if ( xend >= GXM ) xend = GXM; + if ( yend >= GYM ) yend = GYM; + } // monster check for ( int y = ystart; y < yend; ++y ) diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h index 50bf95f3d3..4067d35caa 100644 --- a/crawl-ref/source/monstuff.h +++ b/crawl-ref/source/monstuff.h @@ -129,6 +129,12 @@ int choose_random_nearby_monster(int weight, 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); + /* *********************************************************************** * called from: acr * *********************************************************************** */ diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 8e2d22f5fc..9937d639d6 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -1015,60 +1015,6 @@ static bool _tso_blessing_friendliness(monsters *mon) return true; } -// If there are no nearby followers, try to recall some on the level. -static int _beogh_blessing_recalling() -{ - std::vector<int> recalled; - - FixedVector < char, 2 > empty; - empty[0] = empty[1] = 0; - - monsters *mon; - for (int loopy = 0; loopy < MAX_MONSTERS; loopy++) - { - mon = &menv[loopy]; - - if (mon->type == -1) - continue; - - if (!is_orcish_follower(mon)) - continue; - - recalled.push_back(loopy); - } - if (recalled.empty()) - return 0; - - int count_recalled = 0; - int total = recalled.size(); - int amount = 1 + random2(4) + random2(4); - bool recall_all = (total <= amount); - - for (unsigned int loopy = 0; loopy < recalled.size(); loopy++) - { - mon = &menv[recalled[loopy]]; - - if (!recall_all && total == amount) - recall_all = true; - - if (recall_all || random2(total) < amount) - { - if (empty_surrounds(you.x_pos, you.y_pos, DNGN_FLOOR, 3, - false, empty) - && mon->move_to_pos( coord_def(empty[0], empty[1])) ) - { - count_recalled++; - amount--; - } - else - break; // no more room to place monsters - } - total--; - } - - return (count_recalled); -} - // If you don't currently have any followers, send a small band to help // you out. static bool _beogh_blessing_reinforcement() @@ -1133,24 +1079,19 @@ static bool _beogh_blessing_priesthood(monsters* mon) } // Bless the follower indicated in follower, if any. If there isn't -// one, bless a random follower within sight of the player, if any. +// 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, god_type god, bool (*suitable)(const monsters* mon), bool force) { - std::string pronoun; - std::string blessed; std::string result; monsters *mon; int chance = (force ? coinflip() : random2(20)); - if (chance > 2) - return false; - - bool is_near = false; - // 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]))) @@ -1158,60 +1099,57 @@ bool bless_follower(int follower, if (god != GOD_BEOGH) return false; - // Choose a random follower in LOS, preferably a named one. - follower = choose_random_nearby_monster(0, suitable, true, true); + if (chance > 2) + return false; - if (follower == NON_MONSTER) - { - // Try again, without the LOS restriction. - follower = choose_random_nearby_monster(0, suitable, false, true); - } + // 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 no follower was chosen, either send - // reinforcement or get out. + if (coinflip()) + return false; - // First, try to recall orcish followers on level. - int recalled = _beogh_blessing_recalling(); - bool reinforced = false; + // Try again, without the LOS restriction (5% chance). + follower = choose_random_nearby_monster(0, suitable, false, true); - if (recalled < 3) + if (follower == NON_MONSTER) { - reinforced = _beogh_blessing_reinforcement(); + if (coinflip()) + return false; + + // Try *again*, on the entire level (2.5% chance). + follower = choose_random_monster_on_level(0, suitable, + false, false, true); - if (!reinforced || !recalled && coinflip()) + if (follower == NON_MONSTER) { - // Try again, or possibly send more reinforcement. - if (_beogh_blessing_reinforcement()) - reinforced = true; - } - } + // If no follower was found, attempt to send + // reinforcement. + bool reinforced = _beogh_blessing_reinforcement(); - if (recalled || reinforced) - { - pronoun = ""; - blessed = "you"; + if (!reinforced || coinflip()) + { + // Try again, or possibly send more reinforcement. + if (_beogh_blessing_reinforcement()) + reinforced = true; + } - if (recalled) - result = "recalling"; - else if (reinforced) - result = "reinforcement"; - else - result = "recalling and reinforcement"; + if (!reinforced) + return false; - goto blessing_done; + result = "reinforcement"; + goto blessing_done; + } } } } + ASSERT(follower != -1 && follower != NON_MONSTER); + // Else, apply blessing to chosen follower. mon = &menv[follower]; - is_near = mons_near(mon); - - pronoun = (mons_is_unique(mon->type)) ? "" : "your "; - blessed = (is_near) ? mon->name(DESC_PLAIN).c_str() : "follower"; - if (chance == 0) + if (chance == 0) // 5% chance of holy branding, or priesthood { switch (god) { @@ -1259,7 +1197,8 @@ bool bless_follower(int follower, } // Enchant a monster's weapon or armour/shield by one or two points, - // or at least uncurse it, if possible. + // or at least uncurse it, if possible (10% chance). + // This will happen if the above blessing attempts are unsuccessful. if (chance <= 1) { bool affected; @@ -1304,6 +1243,8 @@ bool bless_follower(int follower, } } + // These effects happen if no other blessing was chosen (90%), or if + // the above attempts all were unsuccessful. switch (god) { case GOD_SHINING_ONE: @@ -1330,20 +1271,27 @@ bool bless_follower(int follower, break; } + // deliberate fallthrough for the healing effects case GOD_BEOGH: { // Remove harmful ailments from a monster, or give it full // healing, optionally giving it one extra hit point, if // possible. - if (coinflip() && _blessing_balms(mon)) + if (coinflip()) { - result = "divine balms"; - goto blessing_done; + if (_blessing_balms(mon)) + { + result = "divine balms"; + goto blessing_done; + } + else if (force) + mpr("Couldn't apply balms."); } bool healing = _blessing_healing(mon, false); bool vigour = false; + // Maybe give an extra hit point. if (!healing || coinflip()) vigour = _blessing_healing(mon, true); @@ -1368,26 +1316,34 @@ bool bless_follower(int follower, } blessing_done: - std::string whom = ""; - if (follower != NON_MONSTER) + bool see_follower = false; + + std::string whom = ""; + if (follower == NON_MONSTER) + whom = "you"; + else { - if (!mons_near(mon) || !player_monster_visible(mon)) - whom = "a follower"; - else + if (mons_near(mon) && player_monster_visible(mon)) + see_follower = true; + + if (see_follower) + { whom = get_unique_monster_name(mon); + if (whom.empty()) + whom = "your " + mon->name(DESC_PLAIN); + } + else // cannot see who was blessed + whom = "a follower"; } - 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 - if (mon && is_near) + if (see_follower) { unsigned char old_flash_colour = you.flash_colour; coord_def c(mon->x, mon->y); |