summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-05 08:39:20 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-05 08:39:20 +0000
commit3423bbab5a0f024eeafffe6b8260c8c088647db1 (patch)
tree7ac6d73449b874aba363c80d57a097833bcf7613
parent166e51b5cc6e35ec1bea7dd24e9e6ae549ac3dde (diff)
downloadcrawl-ref-3423bbab5a0f024eeafffe6b8260c8c088647db1.tar.gz
crawl-ref-3423bbab5a0f024eeafffe6b8260c8c088647db1.zip
First attempt at making vampire feeding interruptible. It doesn't work
yet (I had "You stop feeding" followed by "You continue feeding" including full effects), but it's probably better to commit now anyway. Known potions of blood or porridge cannot be quaffed when engorged (alive). Also clean up blood potions check. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4871 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/debug.cc5
-rw-r--r--crawl-ref/source/delay.cc108
-rw-r--r--crawl-ref/source/delay.h13
-rw-r--r--crawl-ref/source/describe.cc3
-rw-r--r--crawl-ref/source/effects.cc13
-rw-r--r--crawl-ref/source/enum.h1
-rw-r--r--crawl-ref/source/food.cc394
-rw-r--r--crawl-ref/source/food.h5
-rw-r--r--crawl-ref/source/initfile.cc1
-rw-r--r--crawl-ref/source/item_use.cc13
-rw-r--r--crawl-ref/source/itemprop.cc10
-rw-r--r--crawl-ref/source/itemprop.h1
-rw-r--r--crawl-ref/source/items.cc23
-rw-r--r--crawl-ref/source/libgui.cc4
-rw-r--r--crawl-ref/source/makeitem.cc2
-rw-r--r--crawl-ref/source/misc.cc34
-rw-r--r--crawl-ref/source/monstuff.cc8
-rw-r--r--crawl-ref/source/religion.cc3
-rw-r--r--crawl-ref/source/spells3.cc4
-rw-r--r--crawl-ref/source/spells4.cc6
20 files changed, 372 insertions, 279 deletions
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index 0aa7ca040b..25c355d1be 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -1245,11 +1245,8 @@ void create_spec_object()
case OBJ_POTIONS:
mitm[thing_created].quantity = 12;
- if (mitm[thing_created].sub_type == POT_BLOOD
- || mitm[thing_created].sub_type == POT_BLOOD_COAGULATED)
- {
+ if (is_blood_potion(mitm[thing_created]))
init_stack_blood_potions(mitm[thing_created]);
- }
break;
case OBJ_FOOD:
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 9b168c5a62..18227db3f8 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -312,9 +312,9 @@ void stop_delay( bool stop_stair_travel )
ASSERT(!crawl_state.is_repeating_cmd() || delay.type == DELAY_MACRO);
const bool butcher_swap_warn =
- delay.type == DELAY_BUTCHER
- && (you.delay_queue.size() >= 2
- && you.delay_queue[1].type == DELAY_WEAPON_SWAP);
+ (delay.type == DELAY_BUTCHER
+ && you.delay_queue.size() >= 2
+ && you.delay_queue[1].type == DELAY_WEAPON_SWAP);
const int butcher_swap_weapon =
butcher_swap_warn? you.delay_queue[1].parm1 : -10;
@@ -408,6 +408,33 @@ void stop_delay( bool stop_stair_travel )
// this to be stoppable, with partial food items implemented. -- bwr
break;
+ case DELAY_FEED_VAMPIRE:
+ {
+ mpr( "You stop draining the corpse." );
+
+ item_def &corpse = (delay.parm1 ? you.inv[delay.parm2]
+ : mitm[delay.parm2]);
+
+ if (!mons_skeleton( corpse.plus ))
+ {
+ if (delay.parm1)
+ dec_inv_item_quantity( delay.parm2, 1 );
+ else
+ dec_mitm_item_quantity( delay.parm2, 1 );
+ }
+ else
+ {
+ mpr("All blood oozes out of the corpse!");
+ bleed_onto_floor(you.x_pos, you.y_pos, corpse.plus, delay.duration,
+ false);
+ corpse.sub_type = CORPSE_SKELETON;
+ corpse.special = 90;
+ corpse.colour = LIGHTGREY;
+ }
+ did_god_conduct(DID_DRINK_BLOOD, 8);
+ pop_delay();
+ break;
+ }
case DELAY_ARMOUR_ON:
case DELAY_ARMOUR_OFF:
// These two have the default action of not being interruptible,
@@ -484,6 +511,15 @@ bool is_being_butchered(const item_def &item)
return (false);
}
+bool is_vampire_feeding()
+{
+ if (!you_are_delayed())
+ return (false);
+
+ const delay_queue_item &delay = you.delay_queue.front();
+ return (delay.type == DELAY_FEED_VAMPIRE);
+}
+
// check whether there are monsters who might be influenced by Recite
// return 0, if no monsters found
// return 1, if eligible audience found
@@ -576,6 +612,13 @@ void handle_delay( void )
if (apply_area_visible(recite_to_monsters, delay.parm1))
viewwindow(true, false);
break;
+ case DELAY_FEED_VAMPIRE:
+ {
+ item_def &corpse = (delay.parm1 ? you.inv[delay.parm2]
+ : mitm[delay.parm2]);
+ vampire_nutrition_per_turn(corpse, -1);
+ break;
+ }
default:
break;
}
@@ -740,9 +783,22 @@ void handle_delay( void )
items_for_multidrop.erase( items_for_multidrop.begin() );
break;
case DELAY_EAT:
- mprf(MSGCH_MULTITURN_ACTION, "You continue %sing.",
- you.species == SP_VAMPIRE ? "drink" : "eat");
+ mpr("You continue eating.", MSGCH_MULTITURN_ACTION);
+ break;
+ case DELAY_FEED_VAMPIRE:
+ {
+ item_def &corpse = (delay.parm1 ? you.inv[delay.parm2]
+ : mitm[delay.parm2]);
+ if (food_is_rotten(corpse))
+ {
+ mpr("This corpse has started to rot.", MSGCH_ROTTEN_MEAT);
+ stop_delay();
+ break;
+ }
+ mprf(MSGCH_MULTITURN_ACTION, "You continue drinking.");
+ vampire_nutrition_per_turn(corpse, 0);
break;
+ }
default:
break;
}
@@ -822,14 +878,37 @@ static void finish_delay(const delay_queue_item &delay)
break;
}
case DELAY_EAT:
- mprf("You finish %sing.",
- you.species == SP_VAMPIRE ? "drink" : "eat");
+ mprf("You finish eating.");
// For chunks, warn the player if they're not getting much
// nutrition.
if (delay.parm1)
chunk_nutrition_message(delay.parm1);
break;
+ case DELAY_FEED_VAMPIRE:
+ {
+ mprf("You finish drinking.");
+ did_god_conduct(DID_DRINK_BLOOD, 8);
+
+ item_def &corpse = (delay.parm1 ? you.inv[delay.parm2]
+ : mitm[delay.parm2]);
+ vampire_nutrition_per_turn(corpse, 1);
+
+ if (!mons_skeleton( corpse.plus ))
+ {
+ if (delay.parm1)
+ dec_inv_item_quantity( delay.parm2, 1 );
+ else
+ dec_mitm_item_quantity( delay.parm2, 1 );
+ }
+ else if (!one_chance_in(4))
+ {
+ corpse.sub_type = CORPSE_SKELETON;
+ corpse.special = 90;
+ corpse.colour = LIGHTGREY;
+ }
+ break;
+ }
case DELAY_MEMORISE:
mpr( "You finish memorising." );
add_spell_to_memory( static_cast<spell_type>( delay.parm1 ) );
@@ -1325,10 +1404,11 @@ static int userdef_interrupt_activity( const delay_queue_item &idelay,
return (true);
}
- if (delay == DELAY_MACRO &&
- clua.callbooleanfn(true, "c_interrupt_macro",
- "sA", interrupt_name, &at))
+ if (delay == DELAY_MACRO && clua.callbooleanfn(true, "c_interrupt_macro",
+ "sA", interrupt_name, &at))
+ {
return (true);
+ }
#endif
return (false);
@@ -1346,8 +1426,8 @@ static bool should_stop_activity(const delay_queue_item &item,
if (userd)
return (userd == 1);
- return (ai == AI_FORCE_INTERRUPT ||
- (Options.activity_interrupts[item.type][ai]));
+ return (ai == AI_FORCE_INTERRUPT
+ || Options.activity_interrupts[item.type][ai]);
}
inline static void monster_warning(activity_interrupt_type ai,
@@ -1547,8 +1627,8 @@ activity_interrupt_type get_activity_interrupt(const std::string &name)
static const char *delay_names[] =
{
- "not_delayed", "eat", "armour_on", "armour_off", "jewellery_on",
- "memorise", "butcher", "weapon_swap", "passwall",
+ "not_delayed", "eat", "vampire_feed", "armour_on", "armour_off",
+ "jewellery_on", "memorise", "butcher", "weapon_swap", "passwall",
"drop_item", "multidrop", "ascending_stairs", "descending_stairs", "recite",
"run", "rest", "travel", "macro", "interruptible", "uninterruptible",
};
diff --git a/crawl-ref/source/delay.h b/crawl-ref/source/delay.h
index 7c00e1bd5f..44df52435c 100644
--- a/crawl-ref/source/delay.h
+++ b/crawl-ref/source/delay.h
@@ -1,7 +1,7 @@
/*
* File: delay.h
* Summary: Functions for handling multi-turn actions.
- *
+ *
* Modified for Crawl Reference by $Author$ on $Date$
*
* Change History (most recent first):
@@ -44,7 +44,7 @@ struct activity_interrupt_data
: apt(AIP_STRING), data(s), context()
{
}
- activity_interrupt_data(const std::string &s)
+ activity_interrupt_data(const std::string &s)
: apt(AIP_STRING), data(s.c_str()), context()
{
}
@@ -72,13 +72,14 @@ struct ait_hp_loss
void start_delay( delay_type type, int turns, int parm1 = 0, int parm2 = 0 );
void stop_delay( bool stop_stair_travel = false );
-bool you_are_delayed( void );
-delay_type current_delay_action( void );
+bool you_are_delayed( void );
+delay_type current_delay_action( void );
int check_recital_audience( void );
void handle_delay( void );
bool is_run_delay(int delay);
bool is_being_butchered(const item_def &item);
+bool is_vampire_feeding( void );
void stop_butcher_delay();
const char *activity_interrupt_name(activity_interrupt_type ai);
@@ -88,8 +89,8 @@ const char *delay_name(int delay);
delay_type get_delay(const std::string &);
void perform_activity();
-bool interrupt_activity( activity_interrupt_type ai,
- const activity_interrupt_data &a
+bool interrupt_activity( activity_interrupt_type ai,
+ const activity_interrupt_data &a
= activity_interrupt_data() );
#endif
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 1820735b53..efc3a0eeb3 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -1699,8 +1699,7 @@ std::string get_item_description( const item_def &item, bool verbose,
case OBJ_POTIONS:
#ifdef DEBUG_BLOOD_POTIONS
// list content of timer vector for blood potions
- if (item.sub_type == POT_BLOOD
- || item.sub_type == POT_BLOOD_COAGULATED)
+ if (is_blood_potion(item))
{
item_def stack = static_cast<item_def>(item);
CrawlHashTable &props = stack.props;
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index e55da931e8..e5cf28d11c 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -1632,12 +1632,8 @@ bool acquirement(object_class_type class_wanted, int agent,
else if (quant > 1)
thing.quantity = quant;
- if (thing.base_type == OBJ_POTIONS
- && (thing.sub_type == POT_BLOOD
- || thing.sub_type == POT_BLOOD_COAGULATED))
- {
+ if (is_blood_potion(thing))
init_stack_blood_potions(thing);
- }
// remove curse flag from item
do_uncurse_item( thing );
@@ -2288,15 +2284,10 @@ static bool food_item_needs_time_check(item_def &item)
}
if (item.base_type == OBJ_FOOD && item.sub_type != FOOD_CHUNK)
- {
return false;
- }
- if (item.base_type == OBJ_POTIONS && item.sub_type != POT_BLOOD
- && item.sub_type != POT_BLOOD_COAGULATED)
- {
+ if (item.base_type == OBJ_POTIONS && !is_blood_potion(item))
return false;
- }
return true;
}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index aa28986432..b73aca2c8e 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -699,6 +699,7 @@ enum delay_type
{
DELAY_NOT_DELAYED,
DELAY_EAT,
+ DELAY_FEED_VAMPIRE,
DELAY_ARMOUR_ON,
DELAY_ARMOUR_OFF,
DELAY_JEWELLERY_ON,
diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc
index 48d2eefd65..77b99b3569 100644
--- a/crawl-ref/source/food.cc
+++ b/crawl-ref/source/food.cc
@@ -55,15 +55,14 @@
#include "tutorial.h"
#include "xom.h"
-static int determine_chunk_effect(int which_chunk_type, bool rotten_chunk);
-static void eat_chunk( int chunk_effect, bool cannibal, int mon_intel = 0);
-static void eating(unsigned char item_class, int item_type);
-static void describe_food_change(int hunger_increment);
-static bool food_change(bool suppress_message);
-static bool vampire_consume_corpse(int mons_type, int mass,
- int chunk_type, bool rotten);
-static void heal_from_food(int hp_amt, int mp_amt, bool unrot,
- bool restore_str);
+static int _determine_chunk_effect(int which_chunk_type, bool rotten_chunk);
+static void _eat_chunk( int chunk_effect, bool cannibal, int mon_intel = 0);
+static void _eating(unsigned char item_class, int item_type);
+static void _describe_food_change(int hunger_increment);
+static bool _food_change(bool suppress_message);
+static bool _vampire_consume_corpse(int slot, bool invent);
+static void _heal_from_food(int hp_amt, int mp_amt, bool unrot,
+ bool restore_str);
/*
**************************************************
@@ -91,10 +90,10 @@ void make_hungry( int hunger_amount, bool suppress_msg )
you.hunger = 0;
// so we don't get two messages, ever.
- bool state_message = food_change(false);
+ bool state_message = _food_change(false);
if (!suppress_msg && !state_message)
- describe_food_change( -hunger_amount );
+ _describe_food_change( -hunger_amount );
} // end make_hungry()
void lessen_hunger( int satiated_amount, bool suppress_msg )
@@ -108,10 +107,10 @@ void lessen_hunger( int satiated_amount, bool suppress_msg )
you.hunger = 12000;
// so we don't get two messages, ever
- bool state_message = food_change(false);
+ bool state_message = _food_change(false);
if (!suppress_msg && !state_message)
- describe_food_change(satiated_amount);
+ _describe_food_change(satiated_amount);
} // end lessen_hunger()
void set_hunger( int new_hunger_level, bool suppress_msg )
@@ -163,7 +162,7 @@ void weapon_switch( int targ )
// 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 )
+static bool _find_butchering_implement( bool fallback )
{
// If wielding a distortion weapon, never attempt to switch away
// automatically.
@@ -341,7 +340,7 @@ bool butchery(int which_corpse)
{
// Try to find a butchering implement.
// If you can butcher by taking off your gloves, don't prompt.
- wpn_switch = find_butchering_implement(!gloved_butcher);
+ wpn_switch = _find_butchering_implement(!gloved_butcher);
removed_gloves = gloved_butcher && !wpn_switch;
if ( removed_gloves )
{
@@ -476,7 +475,7 @@ void lua_push_inv_items(lua_State *ls = NULL)
}
}
-static bool userdef_eat_food()
+static bool _userdef_eat_food()
{
#ifdef CLUA_BINDINGS
lua_push_floor_items(clua.state());
@@ -579,7 +578,7 @@ bool eat_food(bool run_hook, int slot)
// If user hook ran, we don't know whether something
// was eaten or not...
- if (run_hook && userdef_eat_food())
+ if (run_hook && _userdef_eat_food())
return (false);
if (igrd[you.x_pos][you.y_pos] != NON_ITEM && slot == -1)
@@ -601,7 +600,7 @@ bool eat_food(bool run_hook, int slot)
* *
**************************************************
*/
-static std::string how_hungry()
+static std::string _how_hungry()
{
if (you.hunger_state > HS_SATIATED)
return ("full");
@@ -610,7 +609,7 @@ static std::string how_hungry()
return ("hungry");
}
-static bool food_change(bool suppress_message)
+static bool _food_change(bool suppress_message)
{
char newstate = HS_ENGORGED;
bool state_changed = false;
@@ -672,6 +671,13 @@ static bool food_change(bool suppress_message)
"much longer.", MSGCH_WARN);
// give more time because suddenly stopping flying can be lethal
you.duration[DUR_TRANSFORMATION] = 5;
+ if (is_vampire_feeding())
+ stop_delay();
+ }
+ if (newstate == HS_ENGORGED && is_vampire_feeding()) // Alive
+ {
+ mpr("You can't stomach any more blood right now.");
+ stop_delay();
}
}
@@ -700,7 +706,7 @@ static bool food_change(bool suppress_message)
msg += "are feeling ";
if (you.hunger_state == HS_VERY_HUNGRY)
msg += "very ";
- msg += how_hungry();
+ msg += _how_hungry();
msg += ".";
learned_something_new(TUT_YOU_HUNGRY);
break;
@@ -715,7 +721,7 @@ static bool food_change(bool suppress_message)
} // end food_change()
// food_increment is positive for eating, negative for hungering
-static void describe_food_change(int food_increment)
+static void _describe_food_change(int food_increment)
{
int magnitude = (food_increment > 0)?food_increment:(-food_increment);
std::string msg;
@@ -737,7 +743,7 @@ static void describe_food_change(int food_increment)
else
msg += "less ";
- msg += how_hungry().c_str();
+ msg += _how_hungry().c_str();
msg += ".";
mpr(msg.c_str());
} // end describe_food_change()
@@ -759,28 +765,7 @@ void eat_from_inventory(int which_inventory_slot)
item_def& food(you.inv[which_inventory_slot]);
if (food.base_type == OBJ_CORPSES && food.sub_type == CORPSE_BODY)
{
- if (you.species != SP_VAMPIRE)
- return;
-
- const int mons_type = food.plus;
- const bool rotten = food_is_rotten(food);
- const int chunk_type
- = determine_chunk_effect(mons_corpse_effect( mons_type ), rotten);
- const int mass = mons_weight(food.plus)/150;
-
- if (!vampire_consume_corpse(mons_type, mass, chunk_type, rotten))
- return;
-
- if (!mons_skeleton( mons_type ) || one_chance_in(4))
- {
- dec_inv_item_quantity( which_inventory_slot, 1 );
- }
- else
- {
- food.sub_type = CORPSE_SKELETON;
- food.special = 90;
- food.colour = LIGHTGREY;
- }
+ _vampire_consume_corpse(which_inventory_slot, true);
return;
}
else if (food.sub_type == FOOD_CHUNK)
@@ -794,10 +779,11 @@ void eat_from_inventory(int which_inventory_slot)
if (rotten && !_player_can_eat_rotten_meat(true))
return;
- eat_chunk(determine_chunk_effect(chunk_type, rotten), cannibal, intel);
+ _eat_chunk(_determine_chunk_effect(chunk_type, rotten), cannibal,
+ intel);
}
else
- eating( food.base_type, food.sub_type );
+ _eating( food.base_type, food.sub_type );
dec_inv_item_quantity( which_inventory_slot, 1 );
} // end eat_from_inventory()
@@ -807,28 +793,12 @@ void eat_floor_item(int item_link)
item_def& food(mitm[item_link]);
if (food.base_type == OBJ_CORPSES && food.sub_type == CORPSE_BODY)
{
- const int mons_type = food.plus;
- const bool rotten = food_is_rotten(food);
- const int chunk_type
- = determine_chunk_effect(mons_corpse_effect( mons_type ), rotten);
- const int mass = mons_weight(food.plus)/150;
-
- if (!vampire_consume_corpse(mons_type, mass, chunk_type, rotten))
+ if (you.species != SP_VAMPIRE)
return;
- if (!mons_skeleton( mons_type ) || one_chance_in(4))
- {
- dec_mitm_item_quantity( item_link, 1 );
- }
- else
- {
- food.sub_type = CORPSE_SKELETON;
- food.special = 90;
- food.colour = LIGHTGREY;
- }
- // dec_mitm_item_quantity( item_link, 1 );
+ if (_vampire_consume_corpse(item_link, false))
+ you.turn_is_over = true;
- you.turn_is_over = 1;
return;
}
else if (food.sub_type == FOOD_CHUNK)
@@ -841,10 +811,11 @@ void eat_floor_item(int item_link)
if (rotten && !_player_can_eat_rotten_meat(true))
return;
- eat_chunk(determine_chunk_effect(chunk_type, rotten), cannibal, intel);
+ _eat_chunk(_determine_chunk_effect(chunk_type, rotten), cannibal,
+ intel);
}
else
- eating( food.base_type, food.sub_type );
+ _eating( food.base_type, food.sub_type );
you.turn_is_over = true;
@@ -925,7 +896,7 @@ int eat_from_floor()
return (false);
}
-static const char *chunk_flavour_phrase(bool likes_chunks)
+static const char *_chunk_flavour_phrase(bool likes_chunks)
{
const char *phrase =
likes_chunks? "tastes great." : "tastes terrible.";
@@ -957,7 +928,7 @@ void chunk_nutrition_message(int nutrition)
mpr("That was not very filling.");
}
-static int apply_herbivore_chunk_effects(int nutrition)
+static int _apply_herbivore_chunk_effects(int nutrition)
{
int how_herbivorous = player_mutation_level(MUT_HERBIVOROUS);
@@ -967,14 +938,14 @@ static int apply_herbivore_chunk_effects(int nutrition)
return (nutrition);
}
-static int chunk_nutrition(bool likes_chunks)
+static int _chunk_nutrition(bool likes_chunks)
{
int nutrition = CHUNK_BASE_NUTRITION;
if (likes_chunks || you.hunger_state < HS_SATIATED)
{
- return (likes_chunks? nutrition
- : apply_herbivore_chunk_effects(nutrition));
+ return (likes_chunks ? nutrition
+ : _apply_herbivore_chunk_effects(nutrition));
}
const int gourmand =
@@ -994,22 +965,22 @@ static int chunk_nutrition(bool likes_chunks)
epercent);
#endif
- return (apply_herbivore_chunk_effects(effective_nutrition));
+ return (_apply_herbivore_chunk_effects(effective_nutrition));
}
-static void say_chunk_flavour(bool likes_chunks)
+static void _say_chunk_flavour(bool likes_chunks)
{
- mprf("This raw flesh %s", chunk_flavour_phrase(likes_chunks));
+ mprf("This raw flesh %s", _chunk_flavour_phrase(likes_chunks));
}
// never called directly - chunk_effect values must pass
-// through food::determine_chunk_effect() first {dlb}:
-static void eat_chunk( int chunk_effect, bool cannibal, int mon_intel )
+// through food::_determine_chunk_effect() first {dlb}:
+static void _eat_chunk( int chunk_effect, bool cannibal, int mon_intel )
{
bool likes_chunks = (you.omnivorous() ||
player_mutation_level(MUT_CARNIVOROUS));
- int nutrition = chunk_nutrition(likes_chunks);
+ int nutrition = _chunk_nutrition(likes_chunks);
int hp_amt = 0;
bool suppress_msg = false; // do we display the chunk nutrition message?
bool do_eat = false;
@@ -1057,7 +1028,7 @@ static void eat_chunk( int chunk_effect, bool cannibal, int mon_intel )
(chunk_effect == CE_ROTTEN) ? "rotting " : "");
if (you.species == SP_GHOUL)
- heal_from_food(hp_amt, 0, !one_chance_in(4), one_chance_in(5));
+ _heal_from_food(hp_amt, 0, !one_chance_in(4), one_chance_in(5));
do_eat = true;
}
@@ -1076,11 +1047,13 @@ static void eat_chunk( int chunk_effect, bool cannibal, int mon_intel )
mpr("This raw flesh tastes good.");
if (you.species == SP_GHOUL)
- heal_from_food((!one_chance_in(5)) ? hp_amt : 0, 0,
- !one_chance_in(3), false);
+ {
+ _heal_from_food((!one_chance_in(5)? hp_amt : 0), 0,
+ !one_chance_in(3), false);
+ }
}
else
- say_chunk_flavour(likes_chunks);
+ _say_chunk_flavour(likes_chunks);
do_eat = true;
break;
@@ -1101,7 +1074,7 @@ static void eat_chunk( int chunk_effect, bool cannibal, int mon_intel )
return;
} // end eat_chunk()
-static void eating(unsigned char item_class, int item_type)
+static void _eating(unsigned char item_class, int item_type)
{
int temp_rand; // probability determination {dlb}
int food_value = 0;
@@ -1363,6 +1336,142 @@ static void eating(unsigned char item_class, int item_type)
return;
} // end eating()
+// Divide full nutrition by duration, so that each turn you get the same
+// amount of nutrition. Also, experimentally regenerate 1 hp per feeding turn
+// - this is likely too strong.
+// feeding is -1 at start, 1 when finishing, and 0 else
+void vampire_nutrition_per_turn(const item_def &corpse, int feeding)
+{
+ const int mons_type = corpse.plus;
+ const int chunk_type = _determine_chunk_effect(
+ mons_corpse_effect(mons_type), false);
+
+ // This is the exact formula of corpse nutrition for chunk lovers
+ const int max_chunks = mons_weight(mons_type)/150;
+ int chunk_amount = 1 + max_chunks/2;
+ chunk_amount = stepdown_value( chunk_amount, 4, 4, 12, 12 );
+
+ int food_value = CHUNK_BASE_NUTRITION;
+// int mass = CHUNK_BASE_NUTRITION * chunk_amount;
+ const int duration = 1 + chunk_amount/2;
+ bool start_feeding = false;
+ bool during_feeding = false;
+ bool end_feeding = false;
+
+ if (feeding < 0)
+ start_feeding = true;
+ else if (feeding > 0)
+ end_feeding = true;
+ else
+ during_feeding = true;
+
+ switch (mons_type)
+ {
+ case MONS_HUMAN:
+ {
+ food_value += random2avg((you.experience_level * 10)/duration, 2);
+ int hp_amt = 1 + you.experience_level/2;
+
+
+ if (!end_feeding)
+ {
+ if (start_feeding)
+ mpr("This warm blood tastes really delicious!");
+
+ // Human blood gives extra healing during feeding.
+ if (hp_amt >= duration)
+ hp_amt /= duration;
+ else if (random2(duration) < hp_amt)
+ hp_amt = 1;
+
+ _heal_from_food(hp_amt, 0, one_chance_in(duration/2),
+ one_chance_in(duration));
+ }
+ else
+ {
+ // Give the remainder of healing at the end.
+ if (hp_amt > duration)
+ {
+ _heal_from_food(hp_amt % duration, 0,
+ one_chance_in(duration/2),
+ one_chance_in(duration));
+ }
+ }
+ break;
+ }
+ case MONS_ELF:
+ {
+ food_value += random2avg((you.experience_level * 10)/duration, 2);
+
+ if (end_feeding)
+ {
+ // Elven blood gives mana at the end of feeding.
+ const int mp_amt = 1 + random2(3);
+ _heal_from_food(1, mp_amt, one_chance_in(duration/2),
+ one_chance_in(duration));
+ }
+ else if (start_feeding)
+ mpr("This warm blood tastes magically delicious!");
+ break;
+ }
+ default:
+ switch (chunk_type)
+ {
+ case CE_CLEAN:
+ if (start_feeding)
+ mpr("This warm blood tastes delicious!");
+ else if (end_feeding)
+ _heal_from_food(1, 0, one_chance_in(duration), false);
+ break;
+ case CE_CONTAMINATED:
+ food_value = CHUNK_BASE_NUTRITION/2;
+ if (start_feeding)
+ mpr("Somehow this blood was not very filling!");
+ else if (end_feeding)
+ _heal_from_food(1, 0, one_chance_in(duration), false);
+ break;
+ case CE_POISONOUS:
+ make_hungry(CHUNK_BASE_NUTRITION/2, false);
+ // Always print this message - maybe you lost poison res.
+ // due to feeding.
+ mpr("Blech - this blood tastes nasty!");
+ if (poison_player( 1 + random2(3) ))
+ xom_is_stimulated(random2(128));
+ stop_delay();
+ return;
+ case CE_MUTAGEN_RANDOM:
+ food_value = CHUNK_BASE_NUTRITION/2;
+ if (start_feeding)
+ mpr("This blood tastes really weird!");
+ mutate(RANDOM_MUTATION);
+ did_god_conduct( DID_DELIBERATE_MUTATING, 10);
+ xom_is_stimulated(100);
+ if (end_feeding)
+ _heal_from_food(1, 0, false, false);
+ break;
+ case CE_MUTAGEN_BAD:
+ food_value = CHUNK_BASE_NUTRITION/2;
+ if (start_feeding)
+ mpr("This blood tastes *really* weird.");
+ give_bad_mutation();
+ did_god_conduct( DID_DELIBERATE_MUTATING, 10);
+ xom_is_stimulated(random2(200));
+ if (end_feeding)
+ _heal_from_food(1, 0, false, false);
+ break;
+ case CE_HCL:
+ rot_player( 5 + random2(5) );
+ if (disease_player( 50 + random2(100) ))
+ xom_is_stimulated(random2(100));
+ stop_delay();
+ break;
+ }
+ }
+
+ if (!end_feeding)
+ lessen_hunger(food_value / duration, !start_feeding);
+}
+
bool can_ingest(int what_isit, int kindof_thing, bool suppress_msg, bool reqid,
bool check_hunger)
{
@@ -1553,7 +1662,7 @@ bool can_ingest(int what_isit, int kindof_thing, bool suppress_msg, bool reqid,
// see if you can follow along here -- except for the Amulet of the Gourmand
// addition (long missing and requested), what follows is an expansion of how
// chunks were handled in the codebase up to this date ... {dlb}
-static int determine_chunk_effect(int which_chunk_type, bool rotten_chunk)
+static int _determine_chunk_effect(int which_chunk_type, bool rotten_chunk)
{
int this_chunk_effect = which_chunk_type;
@@ -1657,110 +1766,43 @@ static int determine_chunk_effect(int which_chunk_type, bool rotten_chunk)
return (this_chunk_effect);
} // end determine_chunk_effect()
-static bool vampire_consume_corpse(const int mons_type, const int max_chunks,
- const int chunk_type, const bool rotten)
+static bool _vampire_consume_corpse(const int slot, bool invent)
{
- if (!mons_has_blood(mons_type))
+ ASSERT(you.species == SP_VAMPIRE);
+
+ item_def &corpse = (invent ? you.inv[slot]
+ : mitm[slot]);
+
+ ASSERT(corpse.base_type == OBJ_CORPSES);
+ ASSERT(corpse.sub_type == CORPSE_BODY);
+
+ if (!mons_has_blood(corpse.plus))
{
mpr( "There is no blood in this body!" );
return false;
}
- // This is the exact formula of corpse nutrition for chunk lovers
- int chunk_amount = 1 + random2(max_chunks);
- chunk_amount = stepdown_value( chunk_amount, 4, 4, 12, 12 );
- int mass = CHUNK_BASE_NUTRITION * chunk_amount;
-
- int food_value = 0, hp_amt = 0, mp_amt = 0;
-
- if (rotten)
+ if (food_is_rotten(corpse))
{
- if (wearing_amulet(AMU_THE_GOURMAND))
- {
- food_value = mass/2 + random2(you.experience_level * 5);
- mpr("Slurp.");
- did_god_conduct(DID_DRINK_BLOOD, 8);
- }
- else
- {
- mpr("It's not fresh enough.");
- return false;
- }
- }
- else
- {
- hp_amt++;
-
- switch (mons_type)
- {
- case MONS_HUMAN:
- food_value = mass + random2avg(you.experience_level * 10, 2);
- mpr( "This warm blood tastes really delicious!" );
- hp_amt += 1 + random2(1 + you.experience_level);
- break;
-
- case MONS_ELF:
- food_value = mass + random2avg(you.experience_level * 10, 2);
- mpr( "This warm blood tastes magically delicious!" );
- mp_amt += 1 + random2(3);
- break;
-
- default:
- switch (chunk_type)
- {
- case CE_CLEAN:
- food_value = mass;
- mpr( "This warm blood tastes delicious!" );
- break;
- case CE_CONTAMINATED:
- food_value = mass / (random2(3) + 1);
- mpr( "Somehow this blood was not very filling!" );
- break;
- case CE_POISONOUS:
- food_value = -random2(mass/2);
- mpr( "Blech - this blood tastes nasty!" );
- if (poison_player( 3 + random2(4) ))
- xom_is_stimulated(random2(128));
- break;
- case CE_MUTAGEN_RANDOM:
- food_value = random2(mass);
- mpr( "This blood tastes really weird!" );
- mutate(RANDOM_MUTATION);
- did_god_conduct( DID_DELIBERATE_MUTATING, 10);
- xom_is_stimulated(100);
- break;
- case CE_MUTAGEN_BAD:
- food_value = random2(mass/2);
- mpr("This blood tastes *really* weird.");
- give_bad_mutation();
- did_god_conduct( DID_DELIBERATE_MUTATING, 10);
- xom_is_stimulated(random2(200));
- break;
- case CE_HCL:
- rot_player( 10 + random2(10) );
- if (disease_player( 50 + random2(100) ))
- xom_is_stimulated(random2(100));
- break;
- }
- }
- did_god_conduct(DID_DRINK_BLOOD, 8);
+ mpr("It's not fresh enough.");
+ return false;
}
- heal_from_food(hp_amt, mp_amt,
- !rotten && one_chance_in(4), one_chance_in(3));
-
- lessen_hunger( food_value, true );
- describe_food_change(food_value);
-
// The delay for eating a chunk (mass 1000) is 2
// Here the base nutrition value equals that of chunks,
- // but the delay should be greater.
- start_delay( DELAY_EAT, mass / 400 );
+ // but the delay should be smaller.
+ const int max_chunks = mons_weight(corpse.plus)/150;
+ int chunk_amount = 1 + max_chunks/2;
+ chunk_amount = stepdown_value( chunk_amount, 4, 4, 12, 12 );
+
+ start_delay( DELAY_FEED_VAMPIRE, 1 + chunk_amount/2,
+ (int) invent, slot );
+
return true;
-} // end vampire_consume_corpse()
+}
-static void heal_from_food(int hp_amt, int mp_amt, bool unrot,
- bool restore_str)
+static void _heal_from_food(int hp_amt, int mp_amt, bool unrot,
+ bool restore_str)
{
if (hp_amt > 0)
inc_hp(hp_amt, false);
@@ -1779,7 +1821,7 @@ static void heal_from_food(int hp_amt, int mp_amt, bool unrot,
calc_hp();
calc_mp();
-} // end heal_from_food()
+}
int you_max_hunger()
{
diff --git a/crawl-ref/source/food.h b/crawl-ref/source/food.h
index e925531f28..7887258d44 100644
--- a/crawl-ref/source/food.h
+++ b/crawl-ref/source/food.h
@@ -83,7 +83,7 @@ void set_hunger(int new_hunger_level, bool suppress_msg);
* *********************************************************************** */
void weapon_switch( int targ );
-bool can_ingest(int what_isit, int kindof_thing, bool suppress_msg,
+bool can_ingest(int what_isit, int kindof_thing, bool suppress_msg,
bool reqid = false, bool check_hunger = true);
void eat_floor_item(int item_link);
@@ -96,6 +96,9 @@ bool prompt_eat_from_inventory(int slot = -1);
void chunk_nutrition_message(int nutrition);
+void vampire_nutrition_per_turn(const item_def &corpse,
+ int feeding = 0);
+
int you_max_hunger();
int you_min_hunger();
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 58df77173b..bf37c491d2 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -477,6 +477,7 @@ void game_options::set_default_activity_interrupts()
"interrupt_jewellery_on = interrupt_armour_on",
"interrupt_memorise = interrupt_armour_on, stat",
"interrupt_butcher = interrupt_armour_on, teleport, stat",
+ "interrupt_vampire_feed = interrupt_butcher",
"interrupt_passwall = interrupt_butcher",
"interrupt_multidrop = interrupt_butcher",
"interrupt_macro = interrupt_multidrop",
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 2bb7f66607..a6c10853d4 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -3505,11 +3505,19 @@ void drink( int slot )
const bool alreadyknown = item_type_known(you.inv[item_slot]);
+ if (you.hunger_state == HS_ENGORGED && alreadyknown
+ && (is_blood_potion(you.inv[item_slot])
+ || you.inv[item_slot].sub_type == POT_PORRIDGE))
+ {
+ mpr("You are much too full right now.");
+ return;
+ }
+
// 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);
+ (player_in_a_dangerous_place() && you.experience_level > 1);
if (potion_effect(static_cast<potion_type>(you.inv[item_slot].sub_type),
40, alreadyknown))
@@ -3531,8 +3539,7 @@ void drink( int slot )
xom_is_stimulated(255);
}
- if (you.inv[item_slot].sub_type == POT_BLOOD
- || you.inv[item_slot].sub_type == POT_BLOOD_COAGULATED)
+ if (is_blood_potion(you.inv[item_slot]))
{
// always drink oldest potion
remove_oldest_blood_potion(you.inv[item_slot]);
diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc
index 27c2bfe7b2..4108fb0738 100644
--- a/crawl-ref/source/itemprop.cc
+++ b/crawl-ref/source/itemprop.cc
@@ -28,6 +28,7 @@
#include "food.h"
#include "items.h"
#include "itemprop.h"
+#include "it_use2.h"
#include "macro.h"
#include "mon-util.h"
#include "notes.h"
@@ -2156,6 +2157,15 @@ bool food_is_veg( const item_def &item )
return (Food_prop[ Food_index[item.sub_type] ].herb_mod > 0);
}
+bool is_blood_potion( const item_def &item)
+{
+ if (item.base_type != OBJ_POTIONS)
+ return false;
+
+ return (item.sub_type == POT_BLOOD
+ || item.sub_type == POT_BLOOD_COAGULATED);
+}
+
// returns food value for one turn of eating
int food_value( const item_def &item )
{
diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h
index 4d09609ce1..d24246a64d 100644
--- a/crawl-ref/source/itemprop.h
+++ b/crawl-ref/source/itemprop.h
@@ -710,6 +710,7 @@ int ring_has_pluses( const item_def &item );
// food functions:
bool food_is_meat( const item_def &item );
bool food_is_veg( const item_def &item );
+bool is_blood_potion( const item_def &item );
int food_value( const item_def &item );
int food_turns( const item_def &item );
bool can_cut_meat( const item_def &item );
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index 66823ea7c1..be4702016d 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -1533,12 +1533,9 @@ int move_item_to_player( int obj, int quant_got, bool quiet )
you.inv[m].inscription = mitm[obj].inscription;
}
- if (mitm[obj].base_type == OBJ_POTIONS
- && (mitm[obj].sub_type == POT_BLOOD
- || mitm[obj].sub_type == POT_BLOOD_COAGULATED))
- {
+ if (is_blood_potion(mitm[obj]))
pick_up_blood_potions_stack(mitm[obj], quant_got);
- }
+
inc_inv_item_quantity( m, quant_got );
dec_mitm_item_quantity( obj, quant_got );
burden_change();
@@ -1592,9 +1589,7 @@ int move_item_to_player( int obj, int quant_got, bool quiet )
check_note_item(item);
item.quantity = quant_got;
- if (mitm[obj].base_type == OBJ_POTIONS
- && (mitm[obj].sub_type == POT_BLOOD
- || mitm[obj].sub_type == POT_BLOOD_COAGULATED))
+ if (is_blood_potion(mitm[obj]))
{
if (quant_got != mitm[obj].quantity)
{
@@ -1759,9 +1754,7 @@ bool copy_item_to_grid( const item_def &item, int x_plos, int y_plos,
{
inc_mitm_item_quantity( i, quant_drop );
- if (item.base_type == OBJ_POTIONS
- && (item.sub_type == POT_BLOOD
- || item.sub_type == POT_BLOOD_COAGULATED))
+ if (is_blood_potion(item))
{
item_def help = item;
drop_blood_potions_stack(help, quant_drop, x_plos, y_plos);
@@ -1799,9 +1792,7 @@ bool copy_item_to_grid( const item_def &item, int x_plos, int y_plos,
}
move_item_to_grid( &new_item, x_plos, y_plos );
- if (item.base_type == OBJ_POTIONS
- && (item.sub_type == POT_BLOOD
- || item.sub_type == POT_BLOOD_COAGULATED)
+ if (is_blood_potion(item)
&& item.quantity != quant_drop) // partial drop only
{
// since only the oldest potions have been dropped,
@@ -1923,9 +1914,7 @@ bool drop_item( int item_dropped, int quant_drop, bool try_offer )
else if (strstr(you.inv[item_dropped].inscription.c_str(), "=s") != 0)
StashTrack.add_stash();
- if (you.inv[item_dropped].base_type == OBJ_POTIONS
- && (you.inv[item_dropped].sub_type == POT_BLOOD
- || you.inv[item_dropped].sub_type == POT_BLOOD_COAGULATED)
+ if (is_blood_potion(you.inv[item_dropped])
&& you.inv[item_dropped].quantity != quant_drop)
{
// oldest potions have been dropped
diff --git a/crawl-ref/source/libgui.cc b/crawl-ref/source/libgui.cc
index c1c6a7ce6c..517e14f059 100644
--- a/crawl-ref/source/libgui.cc
+++ b/crawl-ref/source/libgui.cc
@@ -1474,9 +1474,7 @@ static int _handle_mouse_motion(int mouse_x, int mouse_y, bool init)
if (wielded)
desc += EOL "[Ctrl-L-Click] Unwield";
else if ( item_type_known(item)
- && (item.sub_type == POT_BLOOD
- || item.sub_type
- == POT_BLOOD_COAGULATED)
+ && is_blood_potion(item)
&& player_knows_spell(
SPELL_SUBLIMATION_OF_BLOOD) )
{
diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc
index 0ccdd227c6..bf0a595bb2 100644
--- a/crawl-ref/source/makeitem.cc
+++ b/crawl-ref/source/makeitem.cc
@@ -2361,7 +2361,7 @@ static void _generate_potion_item(item_def& item, int force_type,
item.sub_type = stype;
}
- if (item.sub_type == POT_BLOOD || item.sub_type == POT_BLOOD_COAGULATED)
+ if (is_blood_potion(item))
init_stack_blood_potions(item);
}
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 18316ca38f..0c1dd4faa9 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -164,9 +164,7 @@ void turn_corpse_into_chunks( item_def &item )
// initialize blood potions with a vector of timers
void init_stack_blood_potions(item_def &stack, int age)
{
- ASSERT(stack.base_type == OBJ_POTIONS);
- ASSERT(stack.sub_type == POT_BLOOD
- || stack.sub_type == POT_BLOOD_COAGULATED);
+ ASSERT(is_blood_potion(stack));
CrawlHashTable &props = stack.props;
props.clear(); // sanity measure
@@ -218,10 +216,7 @@ void maybe_coagulate_blood_potions_floor(int obj)
{
item_def &blood = mitm[obj];
ASSERT(is_valid_item(blood));
- ASSERT(blood.base_type == OBJ_POTIONS);
-
- ASSERT(blood.sub_type == POT_BLOOD
- || blood.sub_type == POT_BLOOD_COAGULATED);
+ ASSERT(is_blood_potion(blood));
CrawlHashTable &props = blood.props;
if (!props.exists("timer"))
@@ -420,10 +415,7 @@ static void _potion_stack_changed_message(item_def &potion, int num_changed,
bool maybe_coagulate_blood_potions_inv(item_def &blood)
{
ASSERT(is_valid_item(blood));
- ASSERT(blood.base_type == OBJ_POTIONS);
-
- ASSERT(blood.sub_type == POT_BLOOD
- || blood.sub_type == POT_BLOOD_COAGULATED);
+ ASSERT(is_blood_potion(blood));
CrawlHashTable &props = blood.props;
if (!props.exists("timer"))
@@ -728,10 +720,7 @@ bool maybe_coagulate_blood_potions_inv(item_def &blood)
long remove_oldest_blood_potion(item_def &stack)
{
ASSERT(is_valid_item(stack));
- ASSERT(stack.base_type == OBJ_POTIONS);
-
- ASSERT (stack.sub_type == POT_BLOOD
- || stack.sub_type == POT_BLOOD_COAGULATED);
+ ASSERT(is_blood_potion(stack));
CrawlHashTable &props = stack.props;
if (!props.exists("timer"))
@@ -751,10 +740,7 @@ long remove_oldest_blood_potion(item_def &stack)
void remove_newest_blood_potion(item_def &stack, int quant)
{
ASSERT(is_valid_item(stack));
- ASSERT(stack.base_type == OBJ_POTIONS);
-
- ASSERT (stack.sub_type == POT_BLOOD
- || stack.sub_type == POT_BLOOD_COAGULATED);
+ ASSERT(is_blood_potion(stack));
CrawlHashTable &props = stack.props;
if (!props.exists("timer"))
@@ -794,9 +780,7 @@ void drop_blood_potions_stack(item_def &stack, int quant, int x, int y)
return;
ASSERT(quant > 0 && quant <= stack.quantity);
- ASSERT(stack.base_type == OBJ_POTIONS);
- ASSERT(stack.sub_type == POT_BLOOD
- || stack.sub_type == POT_BLOOD_COAGULATED);
+ ASSERT(is_blood_potion(stack));
CrawlHashTable &props = stack.props;
if (!props.exists("timer"))
@@ -847,9 +831,7 @@ void pick_up_blood_potions_stack(item_def &stack, int quant)
if (!is_valid_item(stack))
return;
- ASSERT(stack.base_type == OBJ_POTIONS);
- ASSERT(stack.sub_type == POT_BLOOD
- || stack.sub_type == POT_BLOOD_COAGULATED);
+ ASSERT(is_blood_potion(stack));
CrawlHashTable &props = stack.props;
if (!props.exists("timer"))
@@ -966,7 +948,7 @@ void split_potions_into_decay( int obj, int amount, bool need_msg )
you.wield_change = true;
you.redraw_quiver = true;
- if (potion.sub_type == POT_BLOOD || potion.sub_type == POT_BLOOD_COAGULATED)
+ if (is_blood_potion(potion))
{
// We're being nice here, and only decay the *oldest* potions.
for (int i = 0; i < amount; i++)
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 7d73b0cdc4..0d3f6d01bb 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2663,7 +2663,7 @@ monsters *choose_random_monster_on_level(int weight,
chosen = mon;
}
}
-
+
return chosen;
}
@@ -3505,12 +3505,8 @@ static bool _handle_potion(monsters *monster, bolt & beem)
{
if (dec_mitm_item_quantity( monster->inv[MSLOT_POTION], 1 ))
monster->inv[MSLOT_POTION] = NON_ITEM;
- else if (mitm[monster->inv[MSLOT_POTION]].sub_type == POT_BLOOD
- || mitm[monster->inv[MSLOT_POTION]].sub_type
- == POT_BLOOD_COAGULATED)
- {
+ else if (is_blood_potion(mitm[monster->inv[MSLOT_POTION]]))
remove_oldest_blood_potion(mitm[monster->inv[MSLOT_POTION]]);
- }
if (ident != ID_UNKNOWN_TYPE && was_visible)
set_ident_type(OBJ_POTIONS, potion_type, ident);
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 3cfa93071e..7ab5ce1ce7 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -2565,8 +2565,7 @@ bool is_evil_item(const item_def& item)
retval = (item.sub_type == SCR_TORMENT);
break;
case OBJ_POTIONS:
- retval = (item.sub_type == POT_BLOOD
- || item.sub_type == POT_BLOOD_COAGULATED);
+ retval = is_blood_potion(item);
break;
case OBJ_BOOKS:
retval = (item.sub_type == BOOK_NECROMANCY
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index b5fb8a8bea..36dd8baf38 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -342,9 +342,7 @@ void sublimation(int power)
dec_inv_item_quantity( wielded, 1 );
}
- else if (you.inv[wielded].base_type == OBJ_POTIONS
- && (you.inv[wielded].sub_type == POT_BLOOD
- || you.inv[wielded].sub_type == POT_BLOOD_COAGULATED))
+ else if (is_blood_potion(you.inv[wielded]))
{
mprf("The blood within %s frothes and boils.",
you.inv[wielded].quantity == 1 ? "the flask you are holding"
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index 315edf07c4..e2ff3ab3c1 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -1662,11 +1662,9 @@ bool cast_evaporate(int pow, bolt& beem, int potion)
fire_beam(beem);
// both old and new code use up a potion:
- if (you.inv[potion].sub_type == POT_BLOOD
- || you.inv[potion].sub_type == POT_BLOOD_COAGULATED)
- {
+ if (is_blood_potion(you.inv[potion]))
remove_oldest_blood_potion(you.inv[potion]);
- }
+
dec_inv_item_quantity( potion, 1 );
return (true);