diff options
-rw-r--r-- | crawl-ref/docs/options_guide.txt | 5 | ||||
-rw-r--r-- | crawl-ref/source/delay.cc | 117 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/food.cc | 37 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/mutation.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 16 | ||||
-rw-r--r-- | crawl-ref/source/tutorial.cc | 5 |
9 files changed, 118 insertions, 76 deletions
diff --git a/crawl-ref/docs/options_guide.txt b/crawl-ref/docs/options_guide.txt index b5c7f2352f..bc71862bed 100644 --- a/crawl-ref/docs/options_guide.txt +++ b/crawl-ref/docs/options_guide.txt @@ -1460,6 +1460,7 @@ The following events are logged: - Being put under penance and being forgiven - Receiving a gift from a god (except Xom) - Being able to invoke a godly power for the first time + - Picking up a rune or the orb of zot for the first time - Identifying items (see below) - Killing OOD or unique monsters (see below) - Reaching critical HP levels (see below) @@ -1477,14 +1478,14 @@ note_items = <regexes> artefact (fixed, unrand, or random) or if its short description matches a regex. E.g. - note_items = rod,book,rune,acquirement + note_items = rod,book,acquirement note_monsters = <regex list> Monsters whose name matches an item in this comma-separated list are considered interesting. You can have multiple note_monsters lines. E.g. note_monsters = Klown,orb of fire - + ood_interesting = 8 Monsters which are out of depth (OOD for short) for their current level, e.g. a dragon on level 2, will be noted if they 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; |