diff options
Diffstat (limited to 'crawl-ref/source/delay.cc')
-rw-r--r-- | crawl-ref/source/delay.cc | 185 |
1 files changed, 139 insertions, 46 deletions
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index c72a15f30b..e9ee8bff90 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -38,10 +38,12 @@ #include "religion.h" #include "spl-util.h" #include "stash.h" +#include "state.h" #include "stuff.h" #include "travel.h" #include "tutorial.h" #include "view.h" +#include "xom.h" extern std::vector<SelItem> items_for_multidrop; @@ -103,39 +105,25 @@ static void clear_pending_delays() void start_delay( delay_type type, int turns, int parm1, int parm2 ) /***********************************************************/ { + ASSERT(!crawl_state.is_repeating_cmd() || type == DELAY_MACRO); + delay_queue_item delay; delay.type = type; delay.duration = turns; delay.parm1 = parm1; delay.parm2 = parm2; + delay.started = false; // Handle zero-turn delays (possible with butchering). if (turns == 0) { + delay.started = true; // Don't issue startup message. if (push_delay(delay) == 0) finish_delay(delay); return; } - - switch ( delay.type ) - { - case DELAY_ARMOUR_ON: - mpr("You start putting on your armour.", MSGCH_MULTITURN_ACTION); - break; - case DELAY_ARMOUR_OFF: - mpr("You start removing your armour.", MSGCH_MULTITURN_ACTION); - break; - case DELAY_MEMORISE: - mpr("You start memorising the spell.", MSGCH_MULTITURN_ACTION); - break; - case DELAY_PASSWALL: - mpr("You begin to meditate on the wall.", MSGCH_MULTITURN_ACTION); - break; - default: - break; - } push_delay( delay ); } @@ -147,6 +135,8 @@ void stop_delay( void ) delay_queue_item delay = you.delay_queue.front(); + ASSERT(!crawl_state.is_repeating_cmd() || delay.type == DELAY_MACRO); + const bool butcher_swap_warn = delay.type == DELAY_BUTCHER && (you.delay_queue.size() >= 2 @@ -305,6 +295,17 @@ bool is_being_butchered(const item_def &item) return (false); } +// Xom is amused by a potential food source going to waste, and is +// more amused the hungrier you are. +static void xom_check_corpse_waste() +{ + int food_need = 7000 - you.hunger; + if (food_need < 0) + food_need = 0; + + xom_is_stimulated(64 + (191 * food_need / 6000)); +} + void handle_delay( void ) /***********************/ { @@ -313,6 +314,33 @@ void handle_delay( void ) delay_queue_item &delay = you.delay_queue.front(); + if ( !delay.started ) + { + switch ( delay.type ) + { + case DELAY_ARMOUR_ON: + mpr("You start putting on your armour.", MSGCH_MULTITURN_ACTION); + break; + case DELAY_ARMOUR_OFF: + mpr("You start removing your armour.", MSGCH_MULTITURN_ACTION); + break; + case DELAY_BUTCHER: + mpr("You start butchering the corpse.", MSGCH_MULTITURN_ACTION); + break; + case DELAY_MEMORISE: + mpr("You start memorising the spell.", MSGCH_MULTITURN_ACTION); + break; + case DELAY_PASSWALL: + mpr("You begin to meditate on the wall.", MSGCH_MULTITURN_ACTION); + break; + default: + break; + } + delay.started = true; + } + + ASSERT(!crawl_state.is_repeating_cmd() || delay.type == DELAY_MACRO); + // Run delays and Lua delays don't have a specific end time. if (is_run_delay(delay.type)) { @@ -338,24 +366,41 @@ void handle_delay( void ) // Note that a monster could have raised the corpse and another // monster could die and create a corpse with the same ID number... // However, it would not be at the player's square like the - // original and that's why we do it this way. Note that - // we ignore the conversion to skeleton possibility just to - // be nice. -- bwr + // original and that's why we do it this way. if (is_valid_item( mitm[ delay.parm1 ] ) && mitm[ delay.parm1 ].base_type == OBJ_CORPSES && mitm[ delay.parm1 ].x == you.x_pos && mitm[ delay.parm1 ].y == you.y_pos ) { - // special < 100 is the rottenness check - if ( (mitm[delay.parm1].special < 100) && - (delay.parm2 >= 100) ) + if (mitm[ delay.parm1 ].sub_type == CORPSE_SKELETON) { - mpr("The corpse rots.", MSGCH_ROTTEN_MEAT); - delay.parm2 = 99; // don't give the message twice + mpr("The corpse rots away into a skeleton!"); + if (you.mutation[MUT_SAPROVOROUS] == 3) + xom_check_corpse_waste(); + else + xom_is_stimulated(32); + delay.duration = 0; } + else + { + // special < 100 is the rottenness check + if ( (mitm[delay.parm1].special < 100) && + (delay.parm2 >= 100) ) + { + mpr("The corpse rots.", MSGCH_ROTTEN_MEAT); + delay.parm2 = 99; // don't give the message twice + + if (you.species != SP_VAMPIRE + && you.is_undead != US_UNDEAD + && you.mutation[MUT_SAPROVOROUS] < 3) + { + xom_check_corpse_waste(); + } + } - // mark work done on the corpse in case we stop -- bwr - mitm[ delay.parm1 ].plus2++; + // mark work done on the corpse in case we stop -- bwr + mitm[ delay.parm1 ].plus2++; + } } else { @@ -534,6 +579,8 @@ static void finish_delay(const delay_queue_item &delay) { case DNGN_ROCK_WALL: case DNGN_STONE_WALL: + case DNGN_CLEAR_ROCK_WALL: + case DNGN_CLEAR_STONE_WALL: case DNGN_METAL_WALL: case DNGN_GREEN_CRYSTAL_WALL: case DNGN_WAX_WALL: @@ -572,10 +619,28 @@ static void finish_delay(const delay_queue_item &delay) const item_def &item = mitm[delay.parm1]; if (is_valid_item(item) && item.base_type == OBJ_CORPSES) { + + if (item.sub_type == CORPSE_SKELETON) + { + mpr("The corpse rots away into a skeleton just before you " + "finish butchering it!"); + + if (you.mutation[MUT_SAPROVOROUS] == 3) + xom_check_corpse_waste(); + else + xom_is_stimulated(64); + + break; + } + mprf("You finish %s the corpse into pieces.", (you.has_usable_claws() || you.mutation[MUT_FANGS] == 3) ? "ripping" : "chopping"); + if (is_good_god(you.religion) && is_player_same_species(item.plus)) + simple_god_message(" expects more respect for your departed " + "relatives."); + if (you.species == SP_VAMPIRE && (!god_likes_butchery(you.religion) || !you.duration[DUR_PRAYER])) @@ -663,7 +728,8 @@ static void armour_wear_effects(const int item_slot) set_ident_flags(arm, ISFLAG_EQ_ARMOUR_MASK ); mprf("You finish putting on %s.", arm.name(DESC_NOCAP_YOUR).c_str()); - const equipment_type eq_slot = get_armour_slot(arm); + const equipment_type eq_slot = get_armour_slot(arm); + const bool known_cursed = item_known_cursed(arm); if (eq_slot == EQ_BODY_ARMOUR) { @@ -738,15 +804,15 @@ static void armour_wear_effects(const int item_slot) break; case SPARM_STRENGTH: - modify_stat(STAT_STRENGTH, 3, false); + modify_stat(STAT_STRENGTH, 3, false, arm); break; case SPARM_DEXTERITY: - modify_stat(STAT_DEXTERITY, 3, false); + modify_stat(STAT_DEXTERITY, 3, false, arm); break; case SPARM_INTELLIGENCE: - modify_stat(STAT_INTELLIGENCE, 3, false); + modify_stat(STAT_INTELLIGENCE, 3, false, arm); break; case SPARM_PONDEROUSNESS: @@ -795,7 +861,16 @@ static void armour_wear_effects(const int item_slot) { mpr( "Oops, that feels deathly cold." ); learned_something_new(TUT_YOU_CURSED); - xom_is_stimulated(128); + + // Cursed cloaks prevent you from removing body armour + int cloak_mult = 1; + if (get_armour_slot(arm) == EQ_CLOAK) + cloak_mult = 2; + + if (known_cursed) + xom_is_stimulated(32 * cloak_mult); + else + xom_is_stimulated(64 * cloak_mult); } if (eq_slot == EQ_SHIELD) @@ -1002,7 +1077,7 @@ inline static void monster_warning(activity_interrupt_type ai, if (!mon->visible()) return; #ifndef DEBUG_DIAGNOSTICS - if (at.context != "uncharm") + if (at.context == "already seen") { // Only say "comes into view" if the monster wasn't in view // during the previous turn. @@ -1030,18 +1105,33 @@ inline static void monster_warning(activity_interrupt_type ai, break; } } - else + } + else + { + const std::string mweap = + get_monster_desc(mon, false, DESC_NONE); + std::string text = mon->name(DESC_CAP_A); + + if (at.context == "thin air") { - const std::string mweap = - get_monster_desc(mon, false, DESC_NONE); - std::string text = mon->name(DESC_CAP_A) + " comes into view."; - if (!mweap.empty()) - text += " " + mon->pronoun(PRONOUN_CAP) - + " is" + mweap + "."; - print_formatted_paragraph(text, - get_number_of_cols(), - MSGCH_WARN); + if (mon->type == MONS_AIR_ELEMENTAL) + text += " forms itself from the air."; + else + text += " appears from thin air."; } + else if (at.context == "surfaces") + text += " surfaces."; + else if (at.context.find("bursts forth") != std::string::npos) + text += " bursts forth from the water."; + else + text += " comes into view."; + + if (!mweap.empty()) + text += " " + mon->pronoun(PRONOUN_CAP) + + " is" + mweap + "."; + print_formatted_paragraph(text, + get_number_of_cols(), + MSGCH_WARN); } if (Options.tutorial_left) @@ -1080,7 +1170,7 @@ static void paranoid_option_disable( activity_interrupt_type ai, restart.push_back("Ctrl+V"); } - if (Options.autopickup_on && Options.safe_autopickup) + if (Options.autopickup_on) { deactivatees.push_back("autopickup"); Options.autopickup_on = false; @@ -1102,7 +1192,10 @@ bool interrupt_activity( activity_interrupt_type ai, const activity_interrupt_data &at ) { paranoid_option_disable(ai, at); - + + if (crawl_state.is_repeating_cmd()) + return interrupt_cmd_repeat(ai, at); + const int delay = current_delay_action(); if (delay == DELAY_NOT_DELAYED) |