summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-01 21:38:06 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-01 21:38:06 +0000
commit33f39e1feb49c5f7ef0fc748e16195849627faf9 (patch)
treef3f8d209377cc52716735994388c50d75caa9827
parent4eb30eb42d7983767085a9a7bb45556b9b1665e3 (diff)
downloadcrawl-ref-33f39e1feb49c5f7ef0fc748e16195849627faf9.tar.gz
crawl-ref-33f39e1feb49c5f7ef0fc748e16195849627faf9.zip
* Fix some issues with the new food colourings, and make it respect
Vampires' drinking habits. * Allow other channels than MSGCH_TUTORIAL to use formatted strings and use it to send a coloured string through the butcher prompt, thus visibly setting off dangerous corpses. I'd like normal corpses (no patterns in food_colouring.txt matching) not to be highlighted at all, but they're currently shown in lightgrey, that will have to be improved. * Fix Vampire mutation screen displaying poison resistance wrongly. * Add a new option force_more_message whose syntax is copied from travel_stop_message. Any message containing a regex within this listing will enforce a -More- prompt. By default, it's only enabled for "You start to lose your buoyoncy." * Tweak the messages for Kenku flying to fix 1823833. * Make Xom be amused at players teleporting in a labyrinth or when becoming (Near) Starving while in a labyrinth and with little food at their disposal. Yes, it's one of those "Something for everyone" commits. :D git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5416 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/docs/options_guide.txt13
-rw-r--r--crawl-ref/settings/food_colouring.txt3
-rw-r--r--crawl-ref/settings/menu_colours.txt2
-rw-r--r--crawl-ref/source/abl-show.cc33
-rw-r--r--crawl-ref/source/decks.cc2
-rw-r--r--crawl-ref/source/externs.h1
-rw-r--r--crawl-ref/source/food.cc217
-rw-r--r--crawl-ref/source/initfile.cc40
-rw-r--r--crawl-ref/source/item_use.cc7
-rw-r--r--crawl-ref/source/itemname.cc16
-rw-r--r--crawl-ref/source/message.cc149
-rw-r--r--crawl-ref/source/mutation.cc2
-rw-r--r--crawl-ref/source/player.cc10
-rw-r--r--crawl-ref/source/spells3.cc23
-rw-r--r--crawl-ref/source/stuff.cc6
-rw-r--r--crawl-ref/source/xom.cc4
16 files changed, 374 insertions, 154 deletions
diff --git a/crawl-ref/docs/options_guide.txt b/crawl-ref/docs/options_guide.txt
index b8b404f7a2..b5418f5e3d 100644
--- a/crawl-ref/docs/options_guide.txt
+++ b/crawl-ref/docs/options_guide.txt
@@ -45,9 +45,10 @@ The contents of this text are:
explore_greedy, explore_stop, explore_improved,
tc_reachable, tc_dangerous, tc_disconnected,
tc_excluded, tc_exclude_circle,
- travel_stop_message, runrest_ignore_message,
- runrest_ignore_poison, runrest_ignore_monster,
- trapwalk_safe_hp, trap_prompt, rest_wait_both
+ travel_stop_message, force_more_message,
+ runrest_ignore_message, runrest_ignore_poison,
+ runrest_ignore_monster, trapwalk_safe_hp,
+ trap_prompt, rest_wait_both
4-h Stashes.
stash_tracking, stash_filter, annotate_item_class
4-i Command Enhancements.
@@ -772,6 +773,12 @@ travel_stop_message = <list of regexes>
list of such options. It can be included by
include = travel_stoppers.txt
+force_more_message = <list of regexes>
+ Any message that contains a regex specified here, will enforce a
+ -More- prompt, so it can be used to highlight really important
+ events.
+ The syntax is identical to that of travel_stop_message.
+
runrest_ignore_message = <string>
This only works if runrest.lua has already been sourced in
init.txt. Any message containing the string will *not* stop your
diff --git a/crawl-ref/settings/food_colouring.txt b/crawl-ref/settings/food_colouring.txt
index ebdea7fd35..40f8d2055f 100644
--- a/crawl-ref/settings/food_colouring.txt
+++ b/crawl-ref/settings/food_colouring.txt
@@ -5,9 +5,6 @@
msg := message_colour
inv := menu_colour
-# Spriggans don't care for corpses and chunks.
-#
-
msg = darkgrey:.*inedible.*
inv = darkgrey:.*inedible.*
diff --git a/crawl-ref/settings/menu_colours.txt b/crawl-ref/settings/menu_colours.txt
index c3a5c092c0..6f5343e4d0 100644
--- a/crawl-ref/settings/menu_colours.txt
+++ b/crawl-ref/settings/menu_colours.txt
@@ -114,7 +114,7 @@ menu = yellow:.*potion.*(porridge|gluggy white)
# Defaults for normal items
#
menu = lightred:.*equipped.*cursed
-menu = lightgreen:.*equipped.*
+menu = green:.*equipped.*
menu = green:uncursed
menu = red:cursed
menu = lightgrey:^(scroll|potion|ring|amulet)
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc
index d86c658715..b71a0e3b7b 100644
--- a/crawl-ref/source/abl-show.cc
+++ b/crawl-ref/source/abl-show.cc
@@ -822,9 +822,18 @@ bool activate_ability()
std::vector<talent> talents = your_talents(false);
if ( talents.empty() )
{
- // Vampires can't turn into bats when full of blood.
+ // Give messages if the character cannot use innate talents right now.
+ // * Vampires can't turn into bats when full of blood.
+ // * Permanent flying (Kenku) cannot be turned off.
if (you.species == SP_VAMPIRE && you.experience_level >= 3)
mpr("Sorry, you're too full to transform right now.");
+ else if (you.species == SP_KENKU && you.experience_level >= 5)
+ {
+ if (you.flight_mode() == FL_FLY)
+ mpr("You're already flying!");
+ else if (you.flight_mode() == FL_LEVITATE)
+ mpr("You can only start flying from the ground.");
+ }
else
mpr("Sorry, you're not good enough to have a special ability.");
@@ -2151,19 +2160,23 @@ std::vector<talent> your_talents( bool check_confused )
_add_talent(talents, ABIL_EVOKE_TURN_INVISIBLE, check_confused );
}
- //jmf: "upgrade" for draconians -- expensive flight
- // note: this ability only applies to this counter
+ // jmf: "upgrade" for draconians -- expensive flight
+ // Note: This ability only applies to this counter.
if (player_equip( EQ_RINGS, RING_LEVITATION )
|| player_equip_ego_type( EQ_BOOTS, SPARM_LEVITATION )
|| scan_randarts( RAP_LEVITATE ))
{
- // Now you can only turn levitation off if you have an
- // activatable item. Potions and miscast effects will
- // have to time out (this makes the miscast effect actually
- // a bit annoying). -- bwr
- _add_talent(talents, you.duration[DUR_LEVITATION] ?
- ABIL_EVOKE_STOP_LEVITATING : ABIL_EVOKE_LEVITATE,
- check_confused);
+ // Has no effect on permanently flying Kenku.
+ if (!you.permanent_levitation() && you.flight_mode() != FL_FLY)
+ {
+ // Now you can only turn levitation off if you have an
+ // activatable item. Potions and miscast effects will
+ // have to time out (this makes the miscast effect actually
+ // a bit annoying). -- bwr
+ _add_talent(talents, you.duration[DUR_LEVITATION] ?
+ ABIL_EVOKE_STOP_LEVITATING : ABIL_EVOKE_LEVITATE,
+ check_confused);
+ }
}
if (player_equip( EQ_RINGS, RING_TELEPORTATION )
diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc
index e6c18f591d..db45b50fdb 100644
--- a/crawl-ref/source/decks.cc
+++ b/crawl-ref/source/decks.cc
@@ -1274,7 +1274,7 @@ void evoke_deck( item_def& deck )
<< std::endl;
}
- if ( !fake_draw )
+ if (!fake_draw)
did_god_conduct(DID_CARDS, brownie_points);
// Always wield change, since the number of cards used/left has
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 461c87bb86..4786cf4c7f 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1710,6 +1710,7 @@ public:
// Messages that stop travel
std::vector<message_filter> travel_stop_message;
+ std::vector<message_filter> force_more_message;
int stash_tracking; // How stashes are tracked
diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc
index ad84a5916b..6638f544b0 100644
--- a/crawl-ref/source/food.cc
+++ b/crawl-ref/source/food.cc
@@ -165,7 +165,7 @@ void weapon_switch( int targ )
autopickup();
}
-// look for a butchering implement. If fallback is true,
+// Look for a butchering implement. If fallback is true,
// prompt the user if no obvious options exist.
// Returns whether a weapon was switched.
static bool _find_butchering_implement( bool fallback )
@@ -181,6 +181,7 @@ static bool _find_butchering_implement( bool fallback )
mprf(MSGCH_WARN,
"You're wielding a weapon of distortion, will not autoswap "
"for butchering.");
+
return (false);
}
// No switching necessary.
@@ -212,14 +213,14 @@ static bool _find_butchering_implement( bool fallback )
if (!fallback)
return false;
- // if we didn't swap above, then we still can't cut...let's call
+ // If we didn't swap above, then we still can't cut...let's call
// wield_weapon() in the "prompt the user" way...
- // prompt for new weapon
+ // Prompt for new weapon.
mpr("What would you like to use?", MSGCH_PROMPT);
wield_weapon( false );
- // let's see if the user did something...
+ // Let's see if the user did something...
return (you.equip[EQ_WEAPON] != old_weapon);
}
@@ -330,7 +331,13 @@ static void _terminate_butchery(bool wpn_switch, bool removed_gloves,
static bool _have_corpses_in_pack(bool remind)
{
- int num = 0;
+ const bool can_bottle = (you.species == SP_VAMPIRE
+ && you.experience_level > 5
+ && (!you.duration[DUR_PRAYER]
+ || !god_likes_butchery(you.religion)));
+
+ int num = 0;
+ int num_bottle = 0;
for (int i = 0; i < ENDOFPACK; i++)
{
@@ -339,17 +346,27 @@ static bool _have_corpses_in_pack(bool remind)
if (!is_valid_item( obj ))
continue;
- if (obj.base_type == OBJ_CORPSES && obj.sub_type == CORPSE_BODY)
- num++;
+ // Only actually count corpses, not skeletons.
+ if (obj.base_type != OBJ_CORPSES || obj.sub_type != CORPSE_BODY)
+ continue;
+
+ // Only saprovorous characters care about rotten food.
+ if (food_is_rotten(obj) && !player_mutation_level(MUT_SAPROVOROUS))
+ continue;
+
+ num++;
+ if (can_bottle && mons_has_blood(obj.plus))
+ num_bottle++;
}
if (num == 0)
return (false);
- std::string verb = (you.species == SP_VAMPIRE
- && you.experience_level > 5) ? "bottle" : "butcher";
- std::string noun, pronoun;
+ std::string verb = (num_bottle ? (num == num_bottle ? "bottle"
+ : "bottle or butcher")
+ : "butcher");
+ std::string noun, pronoun;
if (num == 1)
{
noun = "corpse";
@@ -370,8 +387,8 @@ static bool _have_corpses_in_pack(bool remind)
}
else
{
- text << "If you dropped the " << noun << " in your pack on solid "
- << "ground then you could " << verb << " " << pronoun << ".";
+ text << "If you dropped the " << noun << " in your pack "
+ << "then you could " << verb << " " << pronoun << ".";
}
mpr(text.str().c_str());
@@ -440,7 +457,7 @@ bool butchery(int which_corpse)
corpse_id = o;
num_corpses++;
- // return pre-chosen corpse if it exists
+ // Return pre-chosen corpse if it exists.
if (prechosen && corpse_id == which_corpse)
break;
}
@@ -450,9 +467,9 @@ bool butchery(int which_corpse)
{
if (!_have_corpses_in_pack(false))
{
- mprf("There isn't anything to %s here.",
+ mprf("There isn't anything to %sbutcher here.",
(you.species == SP_VAMPIRE
- && you.experience_level > 5) ? "bottle" : "butcher");
+ && you.experience_level > 5) ? "bottle or " : "");
}
return (false);
}
@@ -519,13 +536,41 @@ bool butchery(int which_corpse)
{
corpse_id = -1;
+ std::string corpse_name = mitm[o].name(DESC_NOCAP_A);
+
+ const bool sacrifice = (you.duration[DUR_PRAYER]
+ && god_likes_butchery(you.religion));
+
+ // We don't need to check for undead because
+ // * Mummies can't eat
+ // * Ghouls relish the bad things
+ // * Vampires won't bottle bad corpses
+ if (!sacrifice && !you.is_undead)
+ {
+ // Don't bother colouring if it's only for sacrificing.
+ std::string cprf = menu_colour_item_prefix(mitm[o]);
+ std::string colour = "";
+ std::string colour_off = "";
+ int col = menu_colour(corpse_name, cprf, "pickup");
+
+ if (col != LIGHTGRAY)
+ colour = colour_to_str( col );
+
+ if (!colour.empty())
+ {
+ // Order is important here.
+ colour_off = "</" + colour + ">";
+ colour = "<" + colour + ">";
+ corpse_name = colour + corpse_name + colour_off;
+ }
+ }
+
// Shall we butcher this corpse?
snprintf(info, INFO_SIZE, "%s %s?",
- (!can_bottle_blood_from_corpse(mitm[o].plus)
- || you.duration[DUR_PRAYER]
- && god_likes_butchery(you.religion)) ? "Butcher"
- : "Bottle",
- mitm[o].name(DESC_NOCAP_A).c_str());
+ (sacrifice
+ || !can_bottle_blood_from_corpse(mitm[o].plus)) ?
+ "Butcher" : "Bottle",
+ corpse_name.c_str());
const int result = yesnoquit(info, true, 'N', true, false,
'C', 'D');
@@ -657,19 +702,19 @@ bool prompt_eat_from_inventory(int slot)
{
which_inventory_slot = (slot != -1) ? slot :
prompt_invent_item( "Eat which item?",
- MT_INVLIST,
- OBJ_FOOD,
- true, true, true, 0, NULL,
- OPER_EAT );
+ MT_INVLIST,
+ OBJ_FOOD,
+ true, true, true, 0, NULL,
+ OPER_EAT );
}
else
{
which_inventory_slot = (slot != -1) ? slot :
prompt_invent_item( "Drain what?",
- MT_INVLIST,
- OSEL_VAMP_EAT,
- true, true, true, 0, NULL,
- OPER_EAT );
+ MT_INVLIST,
+ OSEL_VAMP_EAT,
+ true, true, true, 0, NULL,
+ OPER_EAT );
}
if (which_inventory_slot == PROMPT_ABORT)
@@ -745,7 +790,7 @@ bool eat_food(bool run_hook, int slot)
}
return (prompt_eat_from_inventory(slot));
-} // end eat_food()
+}
/*
**************************************************
@@ -754,6 +799,68 @@ bool eat_food(bool run_hook, int slot)
* *
**************************************************
*/
+
+static bool _player_has_enough_food()
+{
+ int food_value = 0;
+ item_def item;
+ for (unsigned slot = 0; slot < ENDOFPACK; ++slot)
+ {
+ item = you.inv[slot];
+ if (!is_valid_item(item))
+ continue;
+
+ if (!can_ingest(item.base_type, item.sub_type, true, true, false))
+ continue;
+
+ if (food_is_rotten(item) && !player_mutation_level(MUT_SAPROVOROUS))
+ continue;
+
+ if (is_poisonous(item))
+ continue;
+
+ if (is_mutagenic(item))
+ continue;
+
+ if (causes_rot(item) && you.species != SP_GHOUL)
+ continue;
+
+ // Vampires can only drain corpses.
+ if (you.species == SP_VAMPIRE)
+ food_value += 3;
+ else
+ {
+ if (item.base_type != OBJ_FOOD)
+ continue;
+ switch (item.sub_type)
+ {
+ case FOOD_CHUNK:
+ if (!player_mutation_level(MUT_HERBIVOROUS))
+ food_value += 2 * item.quantity;
+ break;
+ case FOOD_MEAT_RATION:
+ if (!player_mutation_level(MUT_HERBIVOROUS))
+ food_value += 3 * item.quantity;
+ break;
+ case FOOD_BREAD_RATION:
+ if (!player_mutation_level(MUT_CARNIVOROUS))
+ food_value += 3 * item.quantity;
+ break;
+ default:
+ // Only count snacks if we really like them
+ if (is_preferred_food(item))
+ food_value += item.quantity;
+ break;
+ }
+ }
+ }
+
+ // You have "enough" food if you have, e.g.
+ // 1 meat ration + 1 chunk, or 2 chunks for carnivores, or
+ // 5 items of fruit, or 1 bread ration and 2 fruit items as a herbivore.
+ return (food_value > 5);
+}
+
static std::string _how_hungry()
{
if (you.hunger_state > HS_SATIATED)
@@ -846,6 +953,15 @@ static bool _food_change(bool suppress_message)
else
msg += "are starving!";
mpr(msg.c_str(), MSGCH_FOOD, less_hungry);
+
+ // Xom thinks this is funny if you're in a labyrinth
+ // and are low on food.
+ if (you.level_type == LEVEL_LABYRINTH
+ && !_player_has_enough_food())
+ {
+ xom_is_stimulated(64);
+ }
+
learned_something_new(TUT_YOU_STARVING);
you.check_awaken(500);
break;
@@ -856,6 +972,15 @@ static bool _food_change(bool suppress_message)
else
msg += "are near starving!";
mpr(msg.c_str(), MSGCH_FOOD, less_hungry);
+
+ // Xom thinks this is funny if you're in a labyrinth
+ // and are low on food.
+ if (you.level_type == LEVEL_LABYRINTH
+ && !_player_has_enough_food())
+ {
+ xom_is_stimulated(32);
+ }
+
learned_something_new(TUT_YOU_HUNGRY);
break;
@@ -1122,10 +1247,7 @@ static int _chunk_nutrition(bool likes_chunks)
const int epercent = effective_nutrition * 100 / nutrition;
mprf(MSGCH_DIAGNOSTICS,
"Gourmand factor: %d, chunk base: %d, effective: %d, %%: %d",
- gourmand,
- nutrition,
- effective_nutrition,
- epercent);
+ gourmand, nutrition, effective_nutrition, epercent);
#endif
return (_apply_herbivore_chunk_effects(effective_nutrition));
@@ -1150,8 +1272,8 @@ static void _eat_chunk( int chunk_effect, bool cannibal, int mon_intel )
if (you.species == SP_GHOUL)
{
- nutrition = CHUNK_BASE_NUTRITION;
- hp_amt = 1 + random2(5) + random2(1 + you.experience_level);
+ nutrition = CHUNK_BASE_NUTRITION;
+ hp_amt = 1 + random2(5) + random2(1 + you.experience_level);
suppress_msg = true;
}
@@ -1683,14 +1805,20 @@ void vampire_nutrition_per_turn(const item_def &corpse, int feeding)
lessen_hunger(food_value / duration, !start_feeding);
}
+// Returns true if a food item (also corpses) is poisonous AND the player
+// is not poison resistant.
bool is_poisonous(const item_def &food)
{
if (food.base_type != OBJ_FOOD && food.base_type != OBJ_CORPSES)
return (false);
+ if (player_res_poison())
+ return (false);
+
return (mons_corpse_effect(food.plus) == CE_POISONOUS);
}
+// Returns true if a food item (also corpses) is mutagenic.
bool is_mutagenic(const item_def &food)
{
if (food.base_type != OBJ_FOOD && food.base_type != OBJ_CORPSES)
@@ -1699,6 +1827,7 @@ bool is_mutagenic(const item_def &food)
return (mons_corpse_effect(food.plus) == CE_MUTAGEN_RANDOM);
}
+// Returns true if a food item (also corpses) may cause sickness.
bool is_contaminated(const item_def &food)
{
if (food.base_type != OBJ_FOOD && food.base_type != OBJ_CORPSES)
@@ -1707,9 +1836,10 @@ bool is_contaminated(const item_def &food)
return (mons_corpse_effect(food.plus) == CE_CONTAMINATED);
}
+// Returns true if a food item (also corpses) will cause rotting.
bool causes_rot(const item_def &food)
{
- if (food.base_type != OBJ_FOOD && food.sub_type != FOOD_CHUNK)
+ if (food.base_type != OBJ_FOOD && food.base_type != OBJ_CORPSES)
return (false);
return (mons_corpse_effect(food.plus) == CE_HCL);
@@ -1753,6 +1883,11 @@ static int _player_likes_food_type(int food_type)
// still be edible or even delicious.
bool is_preferred_food(const item_def &food)
{
+ // Vampires don't really have a preferred food type, but they really
+ // like blood potions.
+ if (you.species == SP_VAMPIRE)
+ return (is_blood_potion(food));
+
if (food.base_type != OBJ_FOOD)
return (false);
@@ -1797,7 +1932,7 @@ bool can_ingest(int what_isit, int kindof_thing, bool suppress_msg, bool reqid,
if (you.species == SP_VAMPIRE)
{
if (what_isit == OBJ_CORPSES && kindof_thing == CORPSE_BODY)
- return true;
+ return (true);
if (what_isit == OBJ_POTIONS && (kindof_thing == POT_BLOOD
|| kindof_thing == POT_BLOOD_COAGULATED))
@@ -1887,19 +2022,19 @@ bool can_ingest(int what_isit, int kindof_thing, bool suppress_msg, bool reqid,
if (you.species == SP_VAMPIRE)
{
if (kindof_thing == CORPSE_BODY)
- return true;
+ return (true);
else
{
if (!suppress_msg)
mpr("Blech - you need blood!");
- return false;
+ return (false);
}
}
- return false;
+ return (false);
case OBJ_POTIONS: // called by lua
if (get_ident_type(OBJ_POTIONS, kindof_thing) != ID_KNOWN_TYPE)
- return true;
+ return (true);
switch (kindof_thing)
{
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 0df51a676a..2ec348288b 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -146,12 +146,10 @@ int str_to_colour( const std::string &str, int default_colour,
ASSERT(ARRAYSZ(element_cols) == (EC_RANDOM - EC_FIRE) + 1);
for (ret = 0; ret < 16; ret++)
- {
if (str == cols[ret])
break;
- }
- // check for alternate spellings
+ // Check for alternate spellings.
if (ret == 16)
{
if (str == "lightgray")
@@ -177,7 +175,7 @@ int str_to_colour( const std::string &str, int default_colour,
if (ret == 16 && accept_number)
{
- // Check if we have a direct colour index
+ // Check if we have a direct colour index.
const char *s = str.c_str();
char *es = NULL;
const int ci = static_cast<int>(strtol(s, &es, 10));
@@ -188,7 +186,7 @@ int str_to_colour( const std::string &str, int default_colour,
return ((ret == 16) ? default_colour : ret);
}
-// returns -1 if unmatched else returns 0-15
+// Returns -1 if unmatched else returns 0-15.
static int _str_to_channel_colour( const std::string &str )
{
int ret = str_to_colour( str );
@@ -874,6 +872,7 @@ void game_options::reset_options()
note_items.clear();
note_skill_levels.clear();
travel_stop_message.clear();
+ force_more_message.clear();
sound_mappings.clear();
menu_colour_mappings.clear();
menu_colour_prefix_class = false;
@@ -1744,7 +1743,7 @@ void game_options::read_option_line(const std::string &str, bool runscript)
&& key != "race" && key != "class" && key != "ban_pickup"
&& key != "autopickup_exceptions"
&& key != "stop_travel" && key != "sound"
- && key != "travel_stop_message"
+ && key != "travel_stop_message" && key != "force_more_message"
&& key != "drop_filter" && key != "lua_file"
&& key != "note_items" && key != "autoinscribe"
&& key != "note_monsters" && key != "note_messages"
@@ -2400,7 +2399,7 @@ void game_options::read_option_line(const std::string &str, bool runscript)
std::string s = fragments[i].substr( pos + 1 );
trim_string( s );
travel_stop_message.push_back(
- message_filter( channel, s ) );
+ message_filter( channel, s ) );
continue;
}
}
@@ -2409,6 +2408,33 @@ void game_options::read_option_line(const std::string &str, bool runscript)
message_filter( fragments[i] ) );
}
}
+ else if (key == "force_more_message")
+ {
+ std::vector<std::string> fragments = split_string(",", field);
+ for (int i = 0, count = fragments.size(); i < count; ++i)
+ {
+ if (fragments[i].length() == 0)
+ continue;
+
+ std::string::size_type pos = fragments[i].find(":");
+ if (pos && pos != std::string::npos)
+ {
+ std::string prefix = fragments[i].substr(0, pos);
+ int channel = str_to_channel( prefix );
+ if (channel != -1 || prefix == "any")
+ {
+ std::string s = fragments[i].substr( pos + 1 );
+ trim_string( s );
+ force_more_message.push_back(
+ message_filter( channel, s ) );
+ continue;
+ }
+ }
+
+ force_more_message.push_back(
+ message_filter( fragments[i] ) );
+ }
+ }
else if (key == "drop_filter")
{
append_vector(drop_filter, split_string(",", field));
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index d0c1b8e051..2db9c511e4 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -3541,10 +3541,13 @@ void drink( int slot )
if (slot != -1)
item_slot = slot;
else
+ {
item_slot = prompt_invent_item( "Drink which item?",
MT_INVLIST, OBJ_POTIONS,
true, true, true, 0, NULL,
OPER_QUAFF );
+ }
+
if (item_slot == PROMPT_ABORT)
{
canned_msg( MSG_OK );
@@ -3570,8 +3573,8 @@ void drink( int slot )
// The "> 1" part is to reduce the amount of times that Xom is
// stimulated when you are a low-level 1 trying your first unknown
// potions on monsters.
- const bool dangerous =
- (player_in_a_dangerous_place() && you.experience_level > 1);
+ const bool dangerous = (player_in_a_dangerous_place()
+ && you.experience_level > 1);
if (potion_effect(static_cast<potion_type>(you.inv[item_slot].sub_type),
40, alreadyknown))
diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc
index 4b3ca9f252..947937e859 100644
--- a/crawl-ref/source/itemname.cc
+++ b/crawl-ref/source/itemname.cc
@@ -2194,8 +2194,18 @@ const std::string menu_colour_item_prefix(const item_def &item)
switch (item.base_type)
{
+ case OBJ_CORPSES:
+ // Skeletons cannot be eaten.
+ if (item.sub_type == CORPSE_SKELETON)
+ {
+ prefixes.push_back("inedible");
+ break;
+ }
+ // intentional fall-through
case OBJ_FOOD:
- if (!can_ingest(item.base_type, item.sub_type, true, true, false)
+ if (item.base_type != OBJ_CORPSES
+ && !can_ingest(item.base_type, item.sub_type, true, true, false)
+ || you.species == SP_VAMPIRE && !mons_has_blood(item.plus)
|| food_is_rotten(item)
&& !player_mutation_level(MUT_SAPROVOROUS))
{
@@ -2204,9 +2214,7 @@ const std::string menu_colour_item_prefix(const item_def &item)
else if (is_preferred_food(item))
prefixes.push_back("preferred");
- // intentional fall-through
- case OBJ_CORPSES:
- if (is_poisonous(item) && !player_res_poison())
+ if (is_poisonous(item))
prefixes.push_back("poisonous");
else if (is_mutagenic(item))
prefixes.push_back("mutagenic");
diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc
index 009a7d789f..479899d853 100644
--- a/crawl-ref/source/message.cc
+++ b/crawl-ref/source/message.cc
@@ -43,7 +43,7 @@
#include "view.h"
#include "menu.h"
-// circular buffer for keeping past messages
+// Circular buffer for keeping past messages.
message_item Store_Message[ NUM_STORED_MESSAGES ]; // buffer of old messages
int Next_Message = 0; // end of messages
@@ -170,7 +170,7 @@ static char god_message_altar_colour( god_type god )
return (WHITE);
case GOD_ELYVILON:
- return (LIGHTBLUE); // really, LIGHTGREY but that's plain text
+ return (LIGHTBLUE); // Really, LIGHTGREY but that's plain text.
case GOD_OKAWARU:
return (CYAN);
@@ -221,7 +221,7 @@ static char god_message_altar_colour( god_type god )
#ifdef USE_COLOUR_MESSAGES
-// returns a colour or MSGCOL_MUTED
+// Returns a colour or MSGCOL_MUTED.
int channel_to_colour( msg_channel_type channel, int param )
{
if (you.asleep())
@@ -232,7 +232,7 @@ int channel_to_colour( msg_channel_type channel, int param )
switch (Options.channels[ channel ])
{
case MSGCOL_PLAIN:
- // note that if the plain channel is muted, then we're protecting
+ // Note that if the plain channel is muted, then we're protecting
// the player from having that spread to other channels here.
// The intent of plain is to give non-coloured messages, not to
// suppress them.
@@ -338,9 +338,9 @@ int channel_to_colour( msg_channel_type channel, int param )
// cases should be handled above.
if (channel == MSGCH_MONSTER_DAMAGE)
{
- // a special case right now for monster damage (at least until
+ // A special case right now for monster damage (at least until
// the init system is improved)... selecting a specific
- // colour here will result in only the death messages coloured
+ // colour here will result in only the death messages coloured.
if (param == MDAM_DEAD)
ret = Options.channels[ channel ];
else if (Options.channels[ MSGCH_PLAIN ] >= MSGCOL_DEFAULT)
@@ -390,7 +390,7 @@ void mprf( msg_channel_type channel, const char *format, ... )
{
va_list argp;
va_start( argp, format );
- do_message_print( channel, channel == MSGCH_GOD? you.religion : 0,
+ do_message_print( channel, channel == MSGCH_GOD ? you.religion : 0,
format, argp );
va_end( argp );
}
@@ -411,22 +411,37 @@ void mpr(const char *inf, msg_channel_type channel, int param)
fprintf(stderr, "%s\n", inf);
return;
}
+
+ std::string help = inf;
+ if (help.find("</") != std::string::npos)
+ {
+ std::string col = colour_to_str(channel_to_colour(channel));
+ if (!col.empty())
+ help = "<" + col + ">" + help + "</" + col + ">";
+
+ // Handing over to the experts...
+ formatted_mpr(formatted_string::parse_string(help), channel);
+ return;
+ }
+
+
char mbuf[400];
size_t i = 0;
const int stepsize = get_number_of_cols() - 1;
const size_t msglen = strlen(inf);
const int lookback_size = (stepsize < 12 ? 0 : 12);
- // if a message is exactly STEPSIZE characters long,
+
+ // If a message is exactly STEPSIZE characters long,
// it should precisely fit in one line. The printing is thus
// from I to I + STEPSIZE - 1. Stop when I reaches MSGLEN.
while ( i < msglen || i == 0 )
{
strncpy( mbuf, inf + i, stepsize );
mbuf[stepsize] = 0;
- // did the message break?
+ // Did the message break?
if ( i + stepsize < msglen )
{
- // yes, find a nicer place to break it.
+ // Aes, find a nicer place to break it.
int lookback, where = 0;
for ( lookback = 0; lookback < lookback_size; ++lookback )
{
@@ -438,15 +453,16 @@ void mpr(const char *inf, msg_channel_type channel, int param)
if ( lookback != lookback_size )
{
- // found a good spot to break
+ // Found a good spot to break.
mbuf[where] = 0;
- i += where + 1; // skip past the space!
+ i += where + 1; // Skip past the space!
}
else
i += stepsize;
}
else
i += stepsize;
+
base_mpr( mbuf, channel, param );
}
}
@@ -486,8 +502,8 @@ void mpr_comma_separated_list(const std::string prefix,
}
-// checks whether a given message contains patterns relevant for
-// notes, stop_running or sounds and handles these cases
+// Checks whether a given message contains patterns relevant for
+// notes, stop_running or sounds and handles these cases.
static void mpr_check_patterns(const std::string& message,
msg_channel_type channel,
int param)
@@ -555,7 +571,7 @@ static bool channel_message_history(msg_channel_type channel)
}
}
-// adds a given message to the message history
+// Adds a given message to the message history.
static void mpr_store_messages(const std::string& message,
msg_channel_type channel, int param)
{
@@ -570,16 +586,16 @@ static void mpr_store_messages(const std::string& message,
if (Message_Line < num_lines - 1)
Message_Line++;
- // reset colour
+ // Reset colour.
textcolor(LIGHTGREY);
- // equipment lists just waste space in the message recall
+ // Equipment lists just waste space in the message recall.
if (channel_message_history(channel))
{
// Put the message into Store_Message, and move the '---' line forward
- Store_Message[ Next_Message ].text = message;
+ Store_Message[ Next_Message ].text = message;
Store_Message[ Next_Message ].channel = channel;
- Store_Message[ Next_Message ].param = param;
+ Store_Message[ Next_Message ].param = param;
Next_Message++;
if (Next_Message >= NUM_STORED_MESSAGES)
@@ -630,11 +646,11 @@ static void base_mpr(const char *inf, msg_channel_type channel, int param)
const std::string imsg = inf;
const int colour = prepare_message( imsg, channel, param );
- if ( colour == MSGCOL_MUTED )
+ if (colour == MSGCOL_MUTED)
return;
- if (silenced(you.x_pos, you.y_pos) &&
- (channel == MSGCH_SOUND || channel == MSGCH_TALK))
+ if (silenced(you.x_pos, you.y_pos)
+ && (channel == MSGCH_SOUND || channel == MSGCH_TALK))
{
return;
}
@@ -648,6 +664,17 @@ static void base_mpr(const char *inf, msg_channel_type channel, int param)
message_out( Message_Line, colour, inf,
Options.delay_message_clear? 2 : 1 );
+ for (unsigned i = 0; i < Options.force_more_message.size(); ++i)
+ {
+ if (Options.force_more_message[i].is_filtered( channel, imsg ))
+ {
+ more();
+ New_Message_Count = 0;
+ // One more() is quite enough, thank you!
+ break;
+ }
+ }
+
mpr_store_messages(imsg, channel, param);
} // end mpr()
@@ -697,7 +724,7 @@ void formatted_mpr(const formatted_string& fs, msg_channel_type channel,
mpr_store_messages(imsg, channel, param);
}
-// output given string as formatted message(s), but check patterns
+// Output given string as formatted message(s), but check patterns
// for string stripped of tags and store the original tagged string
// for message history. Newlines break the string into multiple
// messages.
@@ -728,9 +755,7 @@ void formatted_message_history(const std::string &st_nocolor,
}
if (wrap_col)
- {
linebreak_string2(st, wrap_col);
- }
std::vector<formatted_string> fss;
formatted_string::parse_string_to_multiple(st, fss);
@@ -750,13 +775,17 @@ void formatted_message_history(const std::string &st_nocolor,
mpr_formatted_output(fs, colour);
- // message playback explicitly only handles colors for
- // the tutorial channel... guess we'll store bare strings
- // for the rest, then.
- if (channel == MSGCH_TUTORIAL)
- mpr_store_messages(fs.to_colour_string(), channel, param);
- else
- mpr_store_messages(unformatted, channel, param);
+ for (unsigned f = 0; f < Options.force_more_message.size(); ++f)
+ {
+ if (Options.force_more_message[f].is_filtered(channel, st_nocolor))
+ {
+ more();
+ New_Message_Count = 0;
+ // One more() is quite enough, thank you!
+ break;
+ }
+ }
+ mpr_store_messages(fs.to_colour_string(), channel, param);
}
}
@@ -779,13 +808,13 @@ void mesclr( bool force )
return;
}
- // turn cursor off -- avoid 'cursor dance'
+ // Turn cursor off -- avoid 'cursor dance'.
cursor_control cs(false);
clear_message_window();
need_prefix = false;
Message_Line = 0;
-} // end mseclr()
+}
void more(void)
{
@@ -808,14 +837,18 @@ void more(void)
int keypress = 0;
if (Options.tutorial_left)
+ {
message_out(crawl_view.msgsz.y - 1,
LIGHTGREY,
"--more-- "
"Press Ctrl-P to reread old messages",
2, false);
+ }
else
+ {
message_out(crawl_view.msgsz.y - 1,
LIGHTGREY, "--more--", 2, false);
+ }
#ifdef USE_TILE
mouse_control mc(MOUSE_MODE_MORE);
@@ -917,12 +950,12 @@ void replay_messages(void)
for (int i = 0; i < num_lines - 2; i++)
{
- // calculate line in circular buffer
+ // Calculate line in circular buffer.
int line = win_start_line + i;
if (line >= NUM_STORED_MESSAGES)
line -= NUM_STORED_MESSAGES;
- // avoid wrap-around
+ // Avoid wrap-around.
if (line == first_message && i != 0)
break;
@@ -935,37 +968,27 @@ void replay_messages(void)
textcolor( colour );
std::string text = Store_Message[ line ].text;
- // for tutorial texts (for now, used for debugging)
- // allow formatted output of tagged messages
- if (Store_Message[ line ].channel == MSGCH_TUTORIAL)
+
+ // Allow formatted output of tagged messages.
+ formatted_string fs = formatted_string::parse_string(text, true);
+ int curcol = 1;
+ for ( unsigned int j = 0; j < fs.ops.size(); ++j )
{
- formatted_string fs = formatted_string::parse_string(text, true);
- int curcol = 1;
- for ( unsigned int j = 0; j < fs.ops.size(); ++j )
+ switch ( fs.ops[j].type )
{
- switch ( fs.ops[j].type )
- {
- case FSOP_COLOUR:
- colour = fs.ops[j].x;
- break;
- case FSOP_TEXT:
- textcolor( colour );
- cgotoxy(curcol, wherey(), GOTO_CRT);
- cprintf(fs.ops[j].text.c_str());
- curcol += multibyte_strlen(fs.ops[j].text);
- break;
- case FSOP_CURSOR:
- break;
- }
+ case FSOP_COLOUR:
+ colour = fs.ops[j].x;
+ break;
+ case FSOP_TEXT:
+ textcolor( colour );
+ cgotoxy(curcol, wherey(), GOTO_CRT);
+ cprintf(fs.ops[j].text.c_str());
+ curcol += multibyte_strlen(fs.ops[j].text);
+ break;
+ case FSOP_CURSOR:
+ break;
}
}
- else
-#if DEBUG_DIAGNOSTICS
- cprintf( "%d: %s", line, text.c_str() );
-#else
- cprintf( "%s", text.c_str() );
-#endif
-
cprintf(EOL);
textcolor(LIGHTGREY);
}
diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc
index 2beb5a54ad..fabf3852aa 100644
--- a/crawl-ref/source/mutation.cc
+++ b/crawl-ref/source/mutation.cc
@@ -1418,7 +1418,7 @@ static void _display_vampire_attributes()
{"Regeneration ", "very fast ", "fast ", "normal ", "normal ", "slow ", "none"},
- {"Poison resistance ", " ", " ", " + ", " + ", " + ", " + "},
+ {"Poison resistance ", " ", " ", " ", " + ", " + ", " + "},
{"Cold resistance ", " ", " ", " ", " + ", " + ", " ++ "},
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 84feba599b..cbf12e67ec 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -1463,13 +1463,13 @@ int player_res_torment(bool)
|| you.species == SP_VAMPIRE && you.hunger_state == HS_STARVING);
}
-// funny that no races are susceptible to poisons {dlb}
+// Funny that no races are susceptible to poisons. {dlb}
// If temp is set to false, temporary sources or resistance won't be counted.
int player_res_poison(bool calc_unid, bool temp)
{
int rp = 0;
- // only thirsty vampires are naturally poison resistant
+ // Only thirsty vampires are naturally poison resistant.
if (you.species == SP_VAMPIRE && you.hunger_state < HS_SATIATED)
rp++;
@@ -6247,9 +6247,11 @@ flight_type player::flight_mode() const
return FL_FLY;
}
else if (is_levitating())
+ {
return (you.duration[DUR_CONTROLLED_FLIGHT]
- || wearing_amulet(AMU_CONTROLLED_FLIGHT)
- ? FL_FLY : FL_LEVITATE);
+ || wearing_amulet(AMU_CONTROLLED_FLIGHT) ? FL_FLY
+ : FL_LEVITATE);
+ }
else
return (FL_NONE);
}
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index 597e5a8887..c58bf6b3a2 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -606,7 +606,7 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area )
if (scan_randarts(RAP_PREVENT_TELEPORTATION))
{
mpr("You feel a strange sense of stasis.");
- return false;
+ return (false);
}
// after this point, we're guaranteed to teleport. Kill the appropriate
@@ -624,7 +624,8 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area )
abyss_teleport( new_abyss_area );
if (you.pet_target != MHITYOU)
you.pet_target = MHITNOT;
- return true;
+
+ return (true);
}
coord_def pos(1, 0);
@@ -671,8 +672,8 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area )
you.moveto(pos.x, pos.y);
- if ((grd[you.x_pos][you.y_pos] != DNGN_FLOOR
- && grd[you.x_pos][you.y_pos] != DNGN_SHALLOW_WATER)
+ if (grd[you.x_pos][you.y_pos] != DNGN_FLOOR
+ && grd[you.x_pos][you.y_pos] != DNGN_SHALLOW_WATER
|| mgrd[you.x_pos][you.y_pos] != NON_MONSTER
|| env.cgrid[you.x_pos][you.y_pos] != EMPTY_CLOUD)
{
@@ -680,11 +681,11 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area )
}
else
{
- // controlling teleport contaminates the player -- bwr
+ // Controlling teleport contaminates the player. -- bwr
contaminate_player(1, true);
}
}
- } // end "if is_controlled"
+ } // end "if is_controlled"
if (!is_controlled)
{
@@ -695,8 +696,8 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area )
newx = random_range(X_BOUND_1 + 1, X_BOUND_2 - 1);
newy = random_range(Y_BOUND_1 + 1, Y_BOUND_2 - 1);
}
- while ((grd[newx][newy] != DNGN_FLOOR
- && grd[newx][newy] != DNGN_SHALLOW_WATER)
+ while (grd[newx][newy] != DNGN_FLOOR
+ && grd[newx][newy] != DNGN_SHALLOW_WATER
|| mgrd[newx][newy] != NON_MONSTER
|| env.cgrid[newx][newy] != EMPTY_CLOUD);
@@ -730,8 +731,10 @@ void you_teleport_now( bool allow_control, bool new_abyss_area )
// teleported to escape from all the monsters chasing him/her,
// since in that case the new dangerous area is almost certainly
// *less* dangerous than the old dangerous area.
- if (randtele && player_in_a_dangerous_place()
- && you.level_type != LEVEL_ABYSS)
+ // Teleporting in a labyrinth is also funny, but only for non-minotaurs.
+ if (randtele
+ && (you.level_type == LEVEL_LABYRINTH && you.species != SP_MINOTAUR
+ || you.level_type != LEVEL_ABYSS && player_in_a_dangerous_place()))
{
xom_is_stimulated(255);
}
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index 2c30a5d7d9..7b25581bd2 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -995,8 +995,9 @@ static const char* _list_allowed_keys(char yes1, char yes2,
return (result.c_str());
}
-// like yesno(), but returns 0 for no, 1 for yes, and -1 for quit
-// alt_yes and alt_yes2 allow up to two synonyms for 'Y'
+// Like yesno(), but returns 0 for no, 1 for yes, and -1 for quit.
+// alt_yes and alt_yes2 allow up to two synonyms for 'Y'.
+// FIXME: This function is shaping up to be a monster. Help!
int yesnoquit( const char* str, bool safe, int safeanswer, bool allow_all,
bool clear_after, char alt_yes, char alt_yes2 )
{
@@ -1006,7 +1007,6 @@ int yesnoquit( const char* str, bool safe, int safeanswer, bool allow_all,
std::string prompt = make_stringf("%s%s ", str ? str : "Buggy prompt?",
_list_allowed_keys(alt_yes, alt_yes2,
safe, allow_all));
-
while (true)
{
mpr(prompt.c_str(), MSGCH_PROMPT);
diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc
index cdeba01205..2a4c74d1ee 100644
--- a/crawl-ref/source/xom.cc
+++ b/crawl-ref/source/xom.cc
@@ -1031,12 +1031,14 @@ void xom_check_lost_item(const item_def& item)
{
// Ignore Abyss area shifts.
if (you.level_type != LEVEL_ABYSS)
+ {
// Abyssal runes are a lot more trouble to find than
// demonic runes, so they get twice the stimulation.
xom_is_stimulated(128, "Xom snickers.", true);
+ }
}
else if (item.plus == RUNE_DEMONIC
- && you.attribute[ATTR_DEMONIC_RUNES] == 0)
+ && you.attribute[ATTR_DEMONIC_RUNES] == 0)
{
xom_is_stimulated(64, "Xom snickers softly.", true);
}