summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-16 09:52:35 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-16 09:52:35 +0000
commit18266441fdeec28e0eba1818726a2c41b2376aa4 (patch)
tree8e3e73051c422692bf925e1d98d82b11797c0fed /crawl-ref/source
parent9775ec72ba0943333eb80d4274d9074741ab3cbb (diff)
downloadcrawl-ref-18266441fdeec28e0eba1818726a2c41b2376aa4.tar.gz
crawl-ref-18266441fdeec28e0eba1818726a2c41b2376aa4.zip
Fix the remaining (known) issues with butchering all corpses in a stash:
* You should now get the "not swapping back" warning also for sac sessions and chained butchery. * Vampires choosing (a)ll from a "Bottle this corpse?" prompt will only attempt to bottle corpses that actually contain blood (so they no longer will be autobutchering bloodless corpses in the stash). Also changed Vampire spell hunger reduction to Thirsty, Very Thirsty: 50% Near Starving, Starving: None git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5075 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/delay.cc117
-rw-r--r--crawl-ref/source/enum.h1
-rw-r--r--crawl-ref/source/food.cc37
-rw-r--r--crawl-ref/source/initfile.cc3
-rw-r--r--crawl-ref/source/mutation.cc2
-rw-r--r--crawl-ref/source/player.cc8
-rw-r--r--crawl-ref/source/religion.cc16
-rw-r--r--crawl-ref/source/tutorial.cc5
8 files changed, 115 insertions, 74 deletions
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 2f8c170abc..7c16e684fd 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -314,15 +314,6 @@ 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
- || delay.type == DELAY_OFFER_CORPSE)
- && 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;
-
// At the very least we can remove any queued delays, right
// now there is no problem with doing this... note that
// any queuing here can only happen from a single command,
@@ -334,11 +325,40 @@ void stop_delay( bool stop_stair_travel )
switch (delay.type)
{
case DELAY_BUTCHER:
+ case DELAY_BOTTLE_BLOOD:
+ case DELAY_OFFER_CORPSE:
+ {
+ bool multiple_corpses = false;
+ bool butcher_swap_warn = false;
+ int wpn_delay = -1;
+ for (unsigned int i = 1; i < you.delay_queue.size(); i++)
+ {
+ if (you.delay_queue[i].type == DELAY_BUTCHER
+ || you.delay_queue[i].type == DELAY_BOTTLE_BLOOD
+ || you.delay_queue[i].type == DELAY_OFFER_CORPSE)
+ {
+ multiple_corpses = true;
+ }
+ else if (you.delay_queue[i].type == DELAY_WEAPON_SWAP)
+ {
+ wpn_delay = i;
+ butcher_swap_warn = true;
+ break;
+ }
+ else
+ break;
+ }
+
+ const std::string butcher_verb =
+ (delay.type == DELAY_BUTCHER ? "butchering" :
+ delay.type == DELAY_BOTTLE_BLOOD ? "bottling blood from"
+ : "sacrificing");
+
// Corpse keeps track of work in plus2 field, see handle_delay() -- bwr
- // FIXME: Also print this message for interruptions in chained
- // butchery/sacrifice session.
if (butcher_swap_warn)
{
+ const int butcher_swap_weapon = you.delay_queue[wpn_delay].parm1;
+
std::string weapon;
if (butcher_swap_weapon == -1)
weapon = "unarmed combat";
@@ -347,16 +367,16 @@ void stop_delay( bool stop_stair_travel )
weapon = "your " +
you.inv[butcher_swap_weapon].name(DESC_BASENAME);
}
- mprf(MSGCH_WARN, "You stop butchering the corpse; not switching "
- "back to %s.",
- weapon.c_str());
+ mprf(MSGCH_WARN, "You stop %s the corpse%s; not switching "
+ "back to %s.", butcher_verb.c_str(),
+ (multiple_corpses ? "s" : ""), weapon.c_str());
}
else
- mpr( "You stop butchering the corpse." );
+ mprf("You stop %s the corpse.", butcher_verb.c_str());
pop_delay();
break;
-
+ }
case DELAY_MEMORISE:
// Losing work here is okay... having to start from
// scratch is a reasonable behaviour. -- bwr
@@ -468,13 +488,6 @@ void stop_delay( bool stop_stair_travel )
}
break;
- case DELAY_OFFER_CORPSE: // one turn
-#ifdef DEBUG_DIAGNOSTICS
- mpr("Stop sacrificing.");
-#endif
- pop_delay();
- break;
-
case DELAY_WEAPON_SWAP: // one turn... too much trouble
case DELAY_DROP_ITEM: // one turn... only used for easy armour drops
case DELAY_JEWELLERY_ON: // one turn
@@ -490,6 +503,7 @@ void stop_delay( bool stop_stair_travel )
void stop_butcher_delay()
{
if (current_delay_action() == DELAY_BUTCHER
+ || current_delay_action() == DELAY_BOTTLE_BLOOD
|| current_delay_action() == DELAY_OFFER_CORPSE)
{
stop_delay();
@@ -521,7 +535,7 @@ bool is_being_butchered(const item_def &item)
return (false);
const delay_queue_item &delay = you.delay_queue.front();
- if (delay.type == DELAY_BUTCHER)
+ if (delay.type == DELAY_BUTCHER || delay.type == DELAY_BOTTLE_BLOOD)
{
const item_def &corpse = mitm[ delay.parm1 ];
return (&corpse == &item);
@@ -615,11 +629,13 @@ void handle_delay( void )
mpr("You start removing your armour.", MSGCH_MULTITURN_ACTION);
break;
case DELAY_BUTCHER:
+ case DELAY_BOTTLE_BLOOD:
mprf(MSGCH_MULTITURN_ACTION, "You start %s the %s.",
- can_bottle_blood_from_corpse(mitm[delay.parm1].plus) ?
- "bottling blood from" : "butchering",
+ (delay.type == DELAY_BOTTLE_BLOOD ? "bottling blood from"
+ : "butchering"),
mitm[delay.parm1].name(DESC_PLAIN).c_str());
+ // also for bottling blood
if (you.duration[DUR_PRAYER]
&& god_hates_butchery(you.religion))
{
@@ -672,8 +688,16 @@ void handle_delay( void )
// First check cases where delay may no longer be valid:
// XXX: need to handle passwall when monster digs -- bwr
- if (delay.type == DELAY_BUTCHER || delay.type == DELAY_OFFER_CORPSE)
+ if (delay.type == DELAY_BUTCHER || delay.type == DELAY_BOTTLE_BLOOD
+ || delay.type == DELAY_OFFER_CORPSE)
{
+ if (delay.type == DELAY_BOTTLE_BLOOD && you.experience_level < 6)
+ {
+ mpr("You cannot bottle blood anymore!");
+ stop_delay();
+ return;
+ }
+
// A monster may have raised the corpse you're chopping up! -- bwr
// Note that a monster could have raised the corpse and another
// monster could die and create a corpse with the same ID number...
@@ -687,7 +711,8 @@ void handle_delay( void )
if (mitm[ delay.parm1 ].sub_type == CORPSE_SKELETON)
{
mpr("The corpse rots away into a skeleton!");
- if (delay.type == DELAY_BUTCHER)
+ if (delay.type == DELAY_BUTCHER
+ || delay.type == DELAY_BOTTLE_BLOOD)
{
if (player_mutation_level(MUT_SAPROVOROUS) == 3)
xom_check_corpse_waste();
@@ -697,7 +722,7 @@ void handle_delay( void )
}
else
{
- // don't attempt to offer a skeleton
+ // Don't attempt to offer a skeleton.
pop_delay();
// Chain onto the next delay.
@@ -730,7 +755,7 @@ void handle_delay( void )
xom_check_corpse_waste();
}
// Vampires won't continue bottling rotting corpses.
- if (can_bottle_blood_from_corpse(mitm[delay.parm1].plus))
+ if (delay.type == DELAY_BOTTLE_BLOOD)
{
mpr("You stop bottling this corpse's foul-smelling "
"blood!");
@@ -822,9 +847,11 @@ void handle_delay( void )
you.inv[delay.parm1].name(DESC_NOCAP_YOUR).c_str());
break;
case DELAY_BUTCHER:
- mprf(MSGCH_MULTITURN_ACTION, "You continue %s the corpse.",
- can_bottle_blood_from_corpse(mitm[delay.parm1].plus)?
- "bottling blood from" : "butchering");
+ mprf(MSGCH_MULTITURN_ACTION, "You continue butchering the corpse.");
+ break;
+ case DELAY_BOTTLE_BLOOD:
+ mprf(MSGCH_MULTITURN_ACTION, "You continue bottling blood from "
+ "the corpse.");
break;
case DELAY_MEMORISE:
mpr("You continue memorising.", MSGCH_MULTITURN_ACTION);
@@ -1026,6 +1053,7 @@ static void finish_delay(const delay_queue_item &delay)
}
case DELAY_BUTCHER:
+ case DELAY_BOTTLE_BLOOD:
{
const item_def &item = mitm[delay.parm1];
if (is_valid_item(item) && item.base_type == OBJ_CORPSES)
@@ -1033,9 +1061,9 @@ static void finish_delay(const delay_queue_item &delay)
if (item.sub_type == CORPSE_SKELETON)
{
mprf("The corpse rots away into a skeleton just before you "
- "finish %s!", can_bottle_blood_from_corpse(item.plus)
- ? "bottling its blood"
- : "butchering");
+ "finish %s!",
+ (delay.type == DELAY_BOTTLE_BLOOD ? "bottling its blood"
+ : "butchering"));
if (player_mutation_level(MUT_SAPROVOROUS) == 3)
xom_check_corpse_waste();
@@ -1045,7 +1073,7 @@ static void finish_delay(const delay_queue_item &delay)
break;
}
- if (can_bottle_blood_from_corpse(item.plus))
+ if (delay.type == DELAY_BOTTLE_BLOOD)
{
turn_corpse_into_blood_potions( mitm[ delay.parm1 ] );
}
@@ -1053,8 +1081,9 @@ static void finish_delay(const delay_queue_item &delay)
{
mprf("You finish %s the %s into pieces.",
(you.has_usable_claws()
- || player_mutation_level(MUT_FANGS) == 3) ? "ripping"
- : "chopping",
+ || player_mutation_level(MUT_FANGS) == 3
+ && you.species != SP_VAMPIRE) ? "ripping"
+ : "chopping",
mitm[delay.parm1].name(DESC_PLAIN).c_str());
if (is_good_god(you.religion) && is_player_same_species(item.plus))
@@ -1068,10 +1097,8 @@ static void finish_delay(const delay_queue_item &delay)
"soul.");
}
- if (you.species == SP_VAMPIRE && you.experience_level < 6
- && mons_has_blood(item.plus)
- && (!god_likes_butchery(you.religion)
- || !you.duration[DUR_PRAYER]))
+ if (you.species == SP_VAMPIRE && delay.type == DELAY_BUTCHER
+ && mons_has_blood(item.plus))
{
mpr("What a waste.");
}
@@ -1716,8 +1743,8 @@ activity_interrupt_type get_activity_interrupt(const std::string &name)
static const char *delay_names[] =
{
"not_delayed", "eat", "vampire_feed", "armour_on", "armour_off",
- "jewellery_on", "memorise", "butcher", "offer_corpse", "weapon_swap",
- "passwall", "drop_item", "multidrop", "ascending_stairs",
+ "jewellery_on", "memorise", "butcher", "bottle_blood", "offer_corpse",
+ "weapon_swap", "passwall", "drop_item", "multidrop", "ascending_stairs",
"descending_stairs", "recite", "run", "rest", "travel", "macro",
"interruptible", "uninterruptible"
};
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 107ccceaae..7335e88de7 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -708,6 +708,7 @@ enum delay_type
DELAY_JEWELLERY_ON,
DELAY_MEMORISE,
DELAY_BUTCHER,
+ DELAY_BOTTLE_BLOOD,
DELAY_OFFER_CORPSE,
DELAY_WEAPON_SWAP, // for easy_butcher
DELAY_PASSWALL,
diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc
index 108d823b7b..83fb8b507b 100644
--- a/crawl-ref/source/food.cc
+++ b/crawl-ref/source/food.cc
@@ -271,7 +271,7 @@ static bool _prepare_butchery(bool can_butcher, bool barehand_butcher,
return (true);
}
-static bool _butcher_corpse(int corpse_id)
+static bool _butcher_corpse(int corpse_id, bool force_butcher = false)
{
ASSERT(corpse_id != -1);
@@ -293,17 +293,19 @@ static bool _butcher_corpse(int corpse_id)
you.religion);
}
- // If we didn't switch weapons, we get in one turn of butchery;
- // otherwise the work has to happen in the delay.
-// if (!wpn_switch && !removed_gloves)
-// ++mitm[corpse_id].plus2;
-
int work_req = 4 - mitm[corpse_id].plus2;
if (work_req < 0)
work_req = 0;
- start_delay(DELAY_BUTCHER, work_req, corpse_id,
- mitm[corpse_id].special);
+
+ delay_type dtype = DELAY_BUTCHER;
+ if (!force_butcher
+ && can_bottle_blood_from_corpse(mitm[corpse_id].plus))
+ {
+ dtype = DELAY_BOTTLE_BLOOD;
+ }
+
+ start_delay(dtype, work_req, corpse_id, mitm[corpse_id].special);
}
you.turn_is_over = true;
@@ -438,6 +440,7 @@ bool butchery(int which_corpse)
// Now pick what you want to butcher. This is only a problem
// if there are several corpses on the square.
bool butcher_all = false;
+ bool bottle_all = false; // for Vampires
for (int o = igrd[you.x_pos][you.y_pos]; o != NON_ITEM; o = mitm[o].link)
{
if (mitm[o].base_type != OBJ_CORPSES
@@ -446,7 +449,10 @@ bool butchery(int which_corpse)
continue;
}
- if (butcher_all)
+ if (bottle_all && !can_bottle_blood_from_corpse(mitm[o].plus))
+ continue;
+
+ if (butcher_all || bottle_all)
corpse_id = o;
else
{
@@ -482,21 +488,26 @@ bool butchery(int which_corpse)
corpse_id = o;
if (result == 2) // (a)ll
- butcher_all = true;
+ {
+ if (can_bottle_blood_from_corpse(mitm[o].plus))
+ bottle_all = true;
+ else
+ butcher_all = true;
+ }
}
}
if (corpse_id != -1)
{
- if (_butcher_corpse(corpse_id))
+ if (_butcher_corpse(corpse_id, butcher_all))
success = true;
- if (!butcher_all)
+ if (!butcher_all && !bottle_all)
break;
}
}
- if (!butcher_all && corpse_id == -1)
+ if (!butcher_all && !bottle_all && corpse_id == -1)
{
mprf("There isn't anything else to %s here.",
you.species == SP_VAMPIRE && you.experience_level >= 6 ?
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 7e168db497..2c090643d7 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -477,6 +477,8 @@ 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_bottle_blood = interrupt_butcher",
+ "interrupt_offer_corpse = interrupt_butcher, hungry",
"interrupt_vampire_feed = interrupt_butcher",
"interrupt_passwall = interrupt_butcher",
"interrupt_multidrop = interrupt_butcher",
@@ -493,7 +495,6 @@ void game_options::set_default_activity_interrupts()
"interrupt_recite = teleport",
"interrupt_uninterruptible =",
"interrupt_weapon_swap =",
- "interrupt_offer_corpse = interrupt_butcher, hungry",
NULL
};
diff --git a/crawl-ref/source/mutation.cc b/crawl-ref/source/mutation.cc
index 45ce62d218..a23aac08fb 100644
--- a/crawl-ref/source/mutation.cc
+++ b/crawl-ref/source/mutation.cc
@@ -1434,7 +1434,7 @@ static void _display_vampire_attributes()
{"Bat Form ", "no ", "no ", "yes ", "yes ", "yes ", "yes "},
- {"Spell hunger ", "full ", "full ", "full ", "reduced ", "lowered ", "none "}
+ {"Spell hunger ", "full ", "full ", "full ", "halved ", "none ", "none "}
};
int current = 0;
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index d7c49328c8..f96b3ec1d2 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -6017,13 +6017,15 @@ void player::make_hungry(int hunger_increase, bool silent)
}
// For semi-undead species (Vampire!) reduce food cost for spells and abilities
-// to 75% (hungry), 50% (very hungry), 25% (near starving), or zero (starving).
+// to 50% (hungry, very hungry) or zero (near starving, starving).
int calc_hunger(int food_cost)
{
if (you.is_undead == US_SEMI_UNDEAD && you.hunger_state < HS_SATIATED)
{
- food_cost *= you.hunger_state;
- food_cost /= 4;
+ if (you.hunger_state <= HS_NEAR_STARVING)
+ return 0;
+
+ return (food_cost/2);
}
return (food_cost);
}
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 52da4191de..af4d0b3ba3 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -4586,7 +4586,7 @@ static bool _god_likes_item(god_type god, const item_def& item)
switch (god)
{
case GOD_KIKUBAAQUDGHA: case GOD_TROG:
- return item.base_type == OBJ_CORPSES;
+ return (item.base_type == OBJ_CORPSES || is_blood_potion(item));
case GOD_NEMELEX_XOBEH:
return !is_deck(item);
@@ -5020,18 +5020,16 @@ std::string god_hates_your_god_reaction(god_type god,
bool god_likes_butchery(god_type god)
{
- return
- god == GOD_OKAWARU ||
- god == GOD_MAKHLEB ||
- god == GOD_TROG ||
- god == GOD_BEOGH ||
- god == GOD_LUGONU;
+ return (god == GOD_OKAWARU
+ || god == GOD_MAKHLEB
+ || god == GOD_TROG
+ || god == GOD_BEOGH
+ || god == GOD_LUGONU);
}
bool god_hates_butchery(god_type god)
{
- return
- god == GOD_ELYVILON;
+ return (god == GOD_ELYVILON);
}
harm_protection_type god_protects_from_harm(god_type god, bool actual)
diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc
index f2480f9445..e77664d47c 100644
--- a/crawl-ref/source/tutorial.cc
+++ b/crawl-ref/source/tutorial.cc
@@ -857,7 +857,7 @@ void tutorial_healing_reminder()
learned_something_new(TUT_NEED_POISON_HEALING);
}
else if (Options.tut_seen_invisible > 0
- && you.num_turns < Options.tut_seen_invisible + 20)
+ && you.num_turns - Options.tut_seen_invisible <= 20)
{
// If we recently encountered an invisible monster, we need a
// special message.
@@ -2434,7 +2434,8 @@ void tutorial_describe_item(const item_def &item)
"<w>d</w>rop menu. On a related note, offering several "
"corpses on a floor square is facilitated by using the "
"<w>c</w>hop prompt where <w>c</w> is a valid synonym "
- "for <w>y</w>es.";
+ "for <w>y</w>es, or directly chopping <w>a</w>ll "
+ "corpses.";
}
#endif
Options.tutorial_events[TUT_SEEN_CARRION] = 0;