summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/docs/crawl_manual.txt5
-rw-r--r--crawl-ref/docs/options_guide.txt24
-rw-r--r--crawl-ref/init.txt1
-rw-r--r--crawl-ref/source/acr.cc33
-rw-r--r--crawl-ref/source/command.cc4
-rw-r--r--crawl-ref/source/dat/database/monspeak.txt22
-rw-r--r--crawl-ref/source/effects.cc4
-rw-r--r--crawl-ref/source/enum.h1
-rw-r--r--crawl-ref/source/externs.h2
-rw-r--r--crawl-ref/source/food.cc2
-rw-r--r--crawl-ref/source/initfile.cc17
-rw-r--r--crawl-ref/source/items.cc4
-rw-r--r--crawl-ref/source/misc.cc31
-rw-r--r--crawl-ref/source/mon-util.cc16
-rw-r--r--crawl-ref/source/monstuff.cc30
-rw-r--r--crawl-ref/source/monstuff.h6
-rw-r--r--crawl-ref/source/religion.cc178
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);