summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-02 06:39:09 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-02 06:39:09 +0000
commit00eb4216eab04d938358d9a382c4afacc4ff5a5f (patch)
treeefad04e2ec0ac072dd4c77c6e3af9ed19febcd6b /crawl-ref
parentfa6393b63b270a07e02ce4c8333b23013b5ded75 (diff)
downloadcrawl-ref-00eb4216eab04d938358d9a382c4afacc4ff5a5f.tar.gz
crawl-ref-00eb4216eab04d938358d9a382c4afacc4ff5a5f.zip
Changed interrupted butchering behaviour as per Johanna's
suggestions/observations: 1) Get rid of option swap_when_safe and its behaviour. 2) If auto-swap butchery is interrupted by teleportation or chagning levels (banishment) then auto-swap back if there's no monsters nearby. 2b) Do the same if butchery is interrupted and then later a large position change happens. 3) If auto-swap butchery is interrupted by something like poison damage, if the butchery is resumed and finished then swap back. 4) If auto-swap butchery is interrupted by a monster, then if the new option prompt_for_swap is set the game will ask if you wish to swap back from your butchering tool. 4b) Do the same if butchery is interrupted and then later a large position change lands you near some hostile monsters. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7717 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/docs/options_guide.txt10
-rw-r--r--crawl-ref/settings/init.txt2
-rw-r--r--crawl-ref/source/acr.cc18
-rw-r--r--crawl-ref/source/beam.cc3
-rw-r--r--crawl-ref/source/delay.cc142
-rw-r--r--crawl-ref/source/delay.h3
-rw-r--r--crawl-ref/source/externs.h4
-rw-r--r--crawl-ref/source/fight.cc12
-rw-r--r--crawl-ref/source/files.cc13
-rw-r--r--crawl-ref/source/initfile.cc4
-rw-r--r--crawl-ref/source/spells3.cc12
11 files changed, 169 insertions, 54 deletions
diff --git a/crawl-ref/docs/options_guide.txt b/crawl-ref/docs/options_guide.txt
index 27d16930e6..384da9e96a 100644
--- a/crawl-ref/docs/options_guide.txt
+++ b/crawl-ref/docs/options_guide.txt
@@ -58,7 +58,7 @@ The contents of this text are:
4-i Command Enhancements.
auto_list, easy_open, easy_unequip, easy_confirm,
allow_self_target, easy_butcher, always_confirm_butcher,
- swap_when_safe, easy_quit_item_prompts, easy_exit_menu,
+ prompt_for_swap, easy_quit_item_prompts, easy_exit_menu,
sort_menus
4-j Message and Display Improvements.
hp_warning, mp_warning, hp_colour, mp_colour,
@@ -976,10 +976,12 @@ always_confirm_butcher = false
one corpse on the square. If there are multiple corpses on a
square, you will always be prompted, regardless of this option.
-swap_when_safe = true
+prompt_for_swap = true
If both this and easy_butcher are true, then if an auto-switch
- butchery is interrupted, the auto-switch will be reversed as
- soon as you are safe again.
+ butchery is interrupted by a hostile monster, the game will
+ ask if you wish to switch back to your weapon. It will also
+ prompt you if after butchery is interupted you teleport or
+ change levels and find yourself near hostile monsters.
easy_quit_item_prompts = true
Setting this option to true allows the quitting of item listing
diff --git a/crawl-ref/settings/init.txt b/crawl-ref/settings/init.txt
index 92ac56ee24..7c27112595 100644
--- a/crawl-ref/settings/init.txt
+++ b/crawl-ref/settings/init.txt
@@ -207,7 +207,7 @@ include = travel_stoppers.txt
# allow_self_target = (yes | no | prompt)
# easy_butcher = false
# always_confirm_butcher = true
-# swap_when_safe = false
+# prompt_for_swap = false
# easy_quit_item_prompts = false
# easy_exit_menu = false
# sort_menus = pickup: true : basename, qualname, curse, qty
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 79ddec8867..599a4cda5f 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -1487,24 +1487,6 @@ static void _input()
if (need_to_autoinscribe())
autoinscribe();
- // XXX: Is there some smart way to avoid autoswitching back if we're
- // just about to continue butchering?
- if (!you.turn_is_over && player_feels_safe
- && you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED]
- && you_tran_can_wear(EQ_WEAPON))
- {
- // Decrease value by 1. (0 means attribute is false, 1 = a, 2 = b, ...)
- int weap = you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] - 1;
- if (weap == ENDOFPACK)
- weap = -1;
-
- weapon_switch(weap);
- print_stats();
-
- // To prevent spam in case the weapon can't be switched back to.
- you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
- }
-
handle_delay();
_center_cursor();
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 7751bd40fd..bde83713a3 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -2358,9 +2358,6 @@ mon_resist_type mons_ench_f2(monsters *monster, bolt &pbolt)
if (!player_monster_visible(monster))
{
- // Don't swap weapons just because you can't see it anymore!
- you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
-
// Also turn off autopickup.
Options.autopickup_on = false;
mpr("Deactivating autopickup; reactivate with Ctrl-A.",
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 7514ffa44d..04c4de8663 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -308,6 +308,10 @@ void start_delay( delay_type type, int turns, int parm1, int parm2 )
delay.parm2 = parm2;
delay.started = false;
+ // Paranoia
+ if (type == DELAY_WEAPON_SWAP)
+ you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
+
// Handle zero-turn delays (possible with butchering).
if (turns == 0)
{
@@ -393,19 +397,12 @@ void stop_delay( bool stop_stair_travel )
"back to %s.", butcher_verb.c_str(),
(multiple_corpses ? "s" : ""), weapon.c_str());
- // Maybe we should do precisely that, but that would entirely
- // defeat the purpose of the weapon swap.
-// you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
-
- if (Options.swap_when_safe)
- {
- // Use weapon slot + 1, so weapon slot 'a' (== 0) doesn't
- // return false when checking if
- // you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED].
- you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED]
- = (butcher_swap_weapon == -1 ? ENDOFPACK
- : butcher_swap_weapon) + 1;
- }
+ // Use weapon slot + 1, so weapon slot 'a' (== 0) doesn't
+ // return false when checking if
+ // you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED].
+ you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED]
+ = (butcher_swap_weapon == -1 ? ENDOFPACK
+ : butcher_swap_weapon) + 1;
}
else
{
@@ -539,6 +536,82 @@ void stop_butcher_delay()
}
}
+void handle_interrupted_swap(bool swap_if_safe, bool force_unsafe)
+{
+ if (!you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED]
+ || !you_tran_can_wear(EQ_WEAPON))
+ {
+ return;
+ }
+
+ // Decrease value by 1. (0 means attribute is false, 1 = a, 2 = b, ...)
+ int weap = you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] - 1;
+ if (weap == ENDOFPACK)
+ weap = -1;
+
+ const bool safe = i_feel_safe() && !force_unsafe;
+ const bool prompt = Options.prompt_for_swap && !safe;
+ const delay_type delay = current_delay_action();
+
+ // If we're going to prompt then update the window so the player can
+ // see what the monsters are.
+ if (prompt)
+ viewwindow(true, false);
+
+ if (delay == DELAY_WEAPON_SWAP)
+ {
+ ASSERT(!"handle_interrupted_swap() called while already swapping "
+ "weapons");
+ you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
+ return;
+ }
+ else if (!you.turn_is_over
+ && (delay == DELAY_ASCENDING_STAIRS
+ || delay == DELAY_DESCENDING_STAIRS))
+ {
+ // We just arrived on the level, let rest of function do its stuff.
+ ;
+ }
+ else if (you.turn_is_over && delay == DELAY_NOT_DELAYED)
+ {
+ // Turn is over, set up a delay to do swapping next turn.
+ if (prompt && yesno("Switch back from butchering tool?", false)
+ || safe && swap_if_safe)
+ {
+ start_delay(DELAY_WEAPON_SWAP, 1, weap);
+ you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
+ }
+ return;
+ }
+ else if (delay != DELAY_NOT_DELAYED)
+ {
+ // If ATTR_WEAPON_SWAP_INTERRUPTED is set while a corpse is being
+ // butchered/bottled/offered, then fake a weapon swap delay.
+ if (delay == DELAY_BUTCHER || delay == DELAY_BOTTLE_BLOOD
+ || delay == DELAY_OFFER_CORPSE)
+ {
+ start_delay(DELAY_WEAPON_SWAP, 1, weap);
+ you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
+ }
+ return;
+ }
+
+ if (safe)
+ {
+ if (!swap_if_safe)
+ return;
+ }
+ else if (!prompt || !yesno("Switch back from butchering tool?", false))
+ {
+ return;
+ }
+
+ weapon_switch(weap);
+ print_stats();
+
+ you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
+}
+
bool you_are_delayed( void )
{
return (!you.delay_queue.empty());
@@ -1151,6 +1224,12 @@ static void _finish_delay(const delay_queue_item &delay)
{
autopickup();
}
+
+ // If we were interrupted while butchering (by poisonig, for
+ // example) then resumed butchering and finished, swap back from
+ // butchering tool if appropriate.
+ if (you.delay_queue.size() == 1)
+ handle_interrupted_swap(true);
}
else
{
@@ -1187,6 +1266,11 @@ static void _finish_delay(const delay_queue_item &delay)
offer_corpse(delay.parm1);
StashTrack.update_stash(); // Don't stash-track this corpse anymore.
}
+ // If we were interrupted while butchering (by poisonig, for
+ // example) then resumed butchering and finished, swap back from
+ // butchering tool if appropriate.
+ if (you.delay_queue.size() == 1)
+ handle_interrupted_swap(true);
break;
}
case DELAY_DROP_ITEM:
@@ -1653,7 +1737,7 @@ static bool _should_stop_activity(const delay_queue_item &item,
|| Options.activity_interrupts[item.type][ai]);
}
-inline static void _monster_warning(activity_interrupt_type ai,
+inline static bool _monster_warning(activity_interrupt_type ai,
const activity_interrupt_data &at,
int atype)
{
@@ -1661,7 +1745,7 @@ inline static void _monster_warning(activity_interrupt_type ai,
{
const monsters* mon = static_cast<const monsters*>(at.data);
if (!mon->visible())
- return;
+ return (false);
if (at.context == "already seen" || at.context == "uncharm")
{
// Only say "comes into view" if the monster wasn't in view
@@ -1726,10 +1810,14 @@ inline static void _monster_warning(activity_interrupt_type ai,
if (Options.tutorial_left)
tutorial_first_monster(*mon);
+
+ return (true);
}
+
+ return (false);
}
-static void _paranoid_option_disable( activity_interrupt_type ai,
+static bool _paranoid_option_disable( activity_interrupt_type ai,
const activity_interrupt_data &at )
{
if (ai == AI_HIT_MONSTER || ai == AI_MONSTER_ATTACKS)
@@ -1758,16 +1846,15 @@ static void _paranoid_option_disable( activity_interrupt_type ai,
restart.end()).c_str());
}
- // Don't switch back after we encountered an invisible creature.
- you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
-
if (Options.tutorial_left)
{
learned_something_new(TUT_INVISIBLE_DANGER);
Options.tut_seen_invisible = you.num_turns;
}
}
+ return (true);
}
+ return (false);
}
// Returns true if any activity was stopped.
@@ -1777,7 +1864,7 @@ bool interrupt_activity( activity_interrupt_type ai,
if (_interrupts_blocked > 0)
return (false);
- _paranoid_option_disable(ai, at);
+ bool was_monst = _paranoid_option_disable(ai, at);
if (crawl_state.is_repeating_cmd())
return interrupt_cmd_repeat(ai, at);
@@ -1802,8 +1889,11 @@ bool interrupt_activity( activity_interrupt_type ai,
if (is_sanctuary(you.pos()))
return (false);
- _monster_warning(ai, at, item.type);
+ was_monst = _monster_warning(ai, at, item.type) || was_monst;
stop_delay();
+ if (was_monst)
+ handle_interrupted_swap(false, true);
+
return (true);
}
@@ -1822,8 +1912,13 @@ bool interrupt_activity( activity_interrupt_type ai,
{
if (is_run_delay( you.delay_queue[j].type ))
{
- _monster_warning(ai, at, you.delay_queue[j].type);
+ was_monst =
+ _monster_warning(ai, at, you.delay_queue[j].type)
+ || was_monst;
+
stop_delay();
+ if (was_monst)
+ handle_interrupted_swap(false, true);
return (true);
}
}
@@ -1831,6 +1926,9 @@ bool interrupt_activity( activity_interrupt_type ai,
// Non-run queued delays can be discarded without any processing.
you.delay_queue.erase( you.delay_queue.begin() + i,
you.delay_queue.end() );
+ if (was_monst)
+ handle_interrupted_swap(false, true);
+
return (true);
}
}
diff --git a/crawl-ref/source/delay.h b/crawl-ref/source/delay.h
index dd47926e18..55cb7bd1d4 100644
--- a/crawl-ref/source/delay.h
+++ b/crawl-ref/source/delay.h
@@ -77,6 +77,9 @@ bool is_run_delay(int delay);
bool is_being_butchered(const item_def &item, bool just_first = true);
bool is_vampire_feeding( void );
void stop_butcher_delay();
+void handle_interrupted_swap(bool swap_if_safe = false,
+ bool force_unsafe = false);
+
void clear_macro_process_key_delay();
const char *activity_interrupt_name(activity_interrupt_type ai);
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index dd52521d4c..f73d24df6c 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1857,8 +1857,8 @@ public:
bool easy_butcher; // autoswap to butchering tool
bool always_confirm_butcher; // even if only one corpse
bool chunks_autopickup; // Autopickup chunks after butchering
- bool swap_when_safe; // If autoswapped butchery was interrupted,
- // swap weapon back when safe.
+ bool prompt_for_swap; // Prompt to switch back from butchering
+ // tool if hostile monsters are around.
bool list_rotten; // list slots for rotting corpses/chunks
bool default_target; // start targeting on a real target
bool autopickup_no_burden; // don't autopickup if it changes burden
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 7e702fd1a6..a47588edb9 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -4199,8 +4199,9 @@ void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk)
void melee_attack::mons_perform_attack_rounds()
{
- const int nrounds = atk->has_hydra_multi_attack() ? atk->number : 4;
- const coord_def pos = defender->pos();
+ const int nrounds = atk->has_hydra_multi_attack() ? atk->number : 4;
+ const coord_def pos = defender->pos();
+ const bool was_delayed = you_are_delayed();
// Melee combat, tell attacker to wield its melee weapon.
atk->wield_melee_weapon();
@@ -4379,6 +4380,13 @@ void melee_attack::mons_perform_attack_rounds()
if (def_copy)
delete def_copy;
+
+ // Inivislbe monster might have interrupted butchering.
+ if (was_delayed && defender->atype() == ACT_PLAYER && perceived_attack
+ && !attacker_visible)
+ {
+ handle_interrupted_swap(false, true);
+ }
}
bool melee_attack::mons_perform_attack()
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index cb3ea53ddf..4bdf77b5f1 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -7,6 +7,7 @@
*/
#include "AppHdr.h"
+#include "delay.h"
#include "files.h"
#include "version.h"
@@ -1343,6 +1344,18 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode,
if (load_mode != LOAD_VISITOR)
dungeon_events.fire_event(DET_ENTERED_LEVEL);
+ if (load_mode == LOAD_ENTER_LEVEL)
+ {
+ // If butchering was interrupted by switching levels (banishment)
+ // then switch back from butchering tool if there's no hostiles
+ // nearby.
+ handle_interrupted_swap(true);
+
+ // Forget about interrupted butchering, since we probably aren't going
+ // to get back to the corpse in time to finish things.
+ you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
+ }
+
return just_created_level;
} // end load()
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index d256558f1d..5763bdc482 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -682,7 +682,7 @@ void game_options::reset_options()
easy_butcher = true;
always_confirm_butcher = false;
chunks_autopickup = true;
- swap_when_safe = true;
+ prompt_for_swap = true;
list_rotten = true;
easy_confirm = CONFIRM_SAFE_EASY;
easy_quit_item_prompts = true;
@@ -2054,7 +2054,7 @@ void game_options::read_option_line(const std::string &str, bool runscript)
else BOOL_OPTION(easy_butcher);
else BOOL_OPTION(always_confirm_butcher);
else BOOL_OPTION(chunks_autopickup);
- else BOOL_OPTION(swap_when_safe);
+ else BOOL_OPTION(prompt_for_swap);
else BOOL_OPTION(list_rotten);
else if (key == "lua_file" && runscript)
{
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index 959ae1bc95..4d89207f0e 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -1259,6 +1259,7 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area )
}
coord_def pos(1, 0);
+ bool large_change = false;
if (is_controlled)
{
@@ -1328,6 +1329,9 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area )
if (pos != you.pos())
clear_trapping_net();
+ if (!see_grid(pos))
+ large_change = true;
+
you.moveto(pos);
if (grd(you.pos()) != DNGN_FLOOR
@@ -1336,6 +1340,7 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area )
|| env.cgrid(you.pos()) != EMPTY_CLOUD)
{
is_controlled = false;
+ large_change = false;
}
else
{
@@ -1396,14 +1401,21 @@ static bool _teleport_player( bool allow_control, bool new_abyss_area )
else if ( see_grid(newpos) )
mpr("Your surroundings seem slightly different.");
else
+ {
mpr("Your surroundings suddenly seem different.");
+ large_change = true;
+ }
you.position = newpos;
// Necessary to update the view centre.
you.moveto(you.pos());
+
}
+ if (large_change)
+ handle_interrupted_swap(true);
+
return !is_controlled;
}