From 22e5db9d1ec1a8119185f3806387519195497b1c Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Mon, 3 Sep 2007 13:41:30 +0000 Subject: Implementing patch 1772497 (improvement to runrest.lua by zelgadis). Also added notes for getting penance, and small fix (patch 1786893 by dolorous). git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2047 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/docs/crawl_options.txt | 5 ++- crawl-ref/init.txt | 1 + crawl-ref/source/debug.cc | 4 +- crawl-ref/source/delay.cc | 33 +++++++++++++-- crawl-ref/source/enum.h | 3 +- crawl-ref/source/lua/runrest.lua | 91 +++++++++++++++++++++++++++++++++++++++- crawl-ref/source/misc.cc | 34 ++++++++++++--- crawl-ref/source/misc.h | 3 +- crawl-ref/source/monspeak.cc | 2 +- crawl-ref/source/notes.cc | 5 +++ crawl-ref/source/notes.h | 1 + crawl-ref/source/religion.cc | 9 ++-- crawl-ref/source/travel.cc | 8 ++-- crawl-ref/source/view.cc | 19 +++++++-- 14 files changed, 192 insertions(+), 26 deletions(-) diff --git a/crawl-ref/docs/crawl_options.txt b/crawl-ref/docs/crawl_options.txt index 5d923a1da4..b265b6e1a2 100644 --- a/crawl-ref/docs/crawl_options.txt +++ b/crawl-ref/docs/crawl_options.txt @@ -228,7 +228,8 @@ The available stock Lua scripts are kills.lua -- improves the Vanquished Creatures list in dump files; currently gives three lists (Vanquished, Friendly, Others) runrest.lua -- allows overriding certain stop conditions when running - New options: runrest_ignore_poison, runrest_ignore_message + New options: runrest_ignore_poison, runrest_ignore_message, + runrest_ignore_monster gearset.lua -- provides commands for switching of complete sets via macro New macroable functions: rememberkit, swapkit eat.lua -- prompts to eat chunks in inventory. @@ -1145,6 +1146,7 @@ use_notes = true - Memorizing a spell of higher level than any learned before - Becoming a worshipper of a god - Abandoning a god + - 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 - Identifying items (see below) @@ -1152,6 +1154,7 @@ use_notes = true - Reaching critical HP levels (see below) - Gaining or losing mutations - Reaching significant levels in a skill (see below) + - Dying You can use the command ':' for manually adding notes. note_items = diff --git a/crawl-ref/init.txt b/crawl-ref/init.txt index aea92bda1f..dd6e7bca55 100644 --- a/crawl-ref/init.txt +++ b/crawl-ref/init.txt @@ -140,6 +140,7 @@ stab_brand = hi:blue # runrest_ignore_message = prayer ends # runrest_ignore_message = You feel.*sick # runrest_ignore_poison = 4:100 +# runrest_ignore_monster = fish:3 # trapwalk_safe_hp = dart:15, needle:25, spear:50 ##### 4-h Stashes ############################### diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index a205576898..a8f3c5c8ae 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -832,9 +832,7 @@ void create_spec_object() mpr( "No such item." ); // Clean up item - mitm[thing_created].base_type = OBJ_UNASSIGNED; - mitm[thing_created].quantity = 0; - + destroy_item(thing_created); return; } type_wanted--; diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index d83e93118b..1638195697 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -995,9 +995,36 @@ inline static void monster_warning(activity_interrupt_type ai, #ifndef DEBUG_DIAGNOSTICS if (at.context != "uncharm") { - std::string text = get_monster_desc(mon, false); - text += " comes into view."; - print_formatted_paragraph(text, get_number_of_cols(), MSGCH_WARN); + // Only say "comes into view" if the monster wasn't in view + // during the previous turn. + if (testbits(mon->flags, MF_WAS_IN_VIEW)) + { + switch(random2(4)) + { + case 0: + mprf(MSGCH_WARN, "%s's nearness makes you nervous.", + mon->name(DESC_CAP_THE).c_str()); + break; + case 1: + mprf(MSGCH_WARN, "%s is too close now for your liking.", + mon->name(DESC_CAP_THE).c_str()); + break; + case 2: + mprf(MSGCH_WARN, "You feel that %s is too close now for comfort.", + mon->name(DESC_NOCAP_THE).c_str()); + break; + default: + mprf(MSGCH_WARN, "%s's presence makes you stop your activity.", + mon->name(DESC_CAP_THE).c_str()); + break; + } + } + else + { + std::string text = get_monster_desc(mon, false); + text += " comes into view."; + print_formatted_paragraph(text, get_number_of_cols(), MSGCH_WARN); + } } if (Options.tutorial_left) diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 7f8849ff2e..6b1c045bf2 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -2506,8 +2506,9 @@ enum monster_flag_type // or that the player has inspected with ? MF_BANISHED = 0x200, // Monster that has been banished. MF_HARD_RESET = 0x400, // Summoned, should not drop gear on reset - MF_CONVERT_ATTEMPT = 0x800 // Orcs only: seen player and was converted + MF_CONVERT_ATTEMPT = 0x800, // Orcs only: seen player and was converted // (or not) + MF_WAS_IN_VIEW = 0x1000 // Was in view during previous turn }; enum mon_dam_level_type diff --git a/crawl-ref/source/lua/runrest.lua b/crawl-ref/source/lua/runrest.lua index 25c1ac44eb..e297dcff49 100644 --- a/crawl-ref/source/lua/runrest.lua +++ b/crawl-ref/source/lua/runrest.lua @@ -10,7 +10,10 @@ -- * Any message in runrest_ignore_message will *not* stop your run. -- * Poison damage of x will be ignored if you have at least y hp if you've -- defined a runrest_ignore_poison = x:y option. --- +-- * Any monster in runrest_ignore_monster will *not* stop your run +-- if it's at least the specified distance away. +-- You can specify this with runrest_ignore_monster = regex:distance. +-- -- IMPORTANT: You must define runrest_ options *after* sourcing runrest.lua. --------------------------------------------------------------------------- @@ -109,3 +112,89 @@ function rr_add_messages(key, value) end chk_lua_option.runrest_ignore_message = rr_add_messages + +----------------------------------------------------------------------- + +g_rr_monsters = { {}, {} } +g_rr_monsters_moving = { {}, {} } + +function rr_add_monster(mons_table, s) + local parts = crawl.split(s, ":") + + if #parts ~= 2 then + return + end + + local regexp = parts[1] + local dist = tonumber(parts[2]) + + if dist == 0 then + return + end + + table.insert( mons_table[1], crawl.regex( regexp ) ) + table.insert( mons_table[2], dist ) +end + +function rr_add_monsters(key, value) + local mons_table + + if (key == "runrest_ignore_monster") then + mons_table = g_rr_monsters + elseif (key == "runrest_ignore_monster_moving") then + mons_table = g_rr_monsters_moving + else + return + end + + local segs = crawl.split(value, ',') + for _, s in ipairs(segs) do + rr_add_monster(mons_table, s) + end +end + +function ch_mon_is_safe(mon, default_is_safe, moving, dist) + if default_is_safe then + return true + end + + local mons_table + + -- If player is moving and the monster is in g_rr_monsters_moving, + -- then we do the distance comparison without decreasing the + -- distance value. + if moving then + mons_table = g_rr_monsters_moving + + for i = 1, #mons_table[1] do + local m = mons_table[1][i] + local min_dist = mons_table[2][i] + + if m:matches(mon.name) then + return min_dist <= dist + end + end + end + + mons_table = g_rr_monsters + + -- Reduce distance by 1 if moving, since the safety check is + -- done *before* moving closer to the monster + if moving then + dist = dist - 1 + end + + for i = 1, #mons_table[1] do + local m = mons_table[1][i] + local min_dist = mons_table[2][i] + + if m:matches(mon.name) then + return min_dist <= dist + end + end + + return false +end + +chk_lua_option.runrest_ignore_monster = rr_add_monsters +chk_lua_option.runrest_ignore_monster_moving = rr_add_monsters diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index ed29826c53..d4212f73aa 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -40,6 +40,7 @@ #include "branch.h" #include "chardump.h" #include "cloud.h" +#include "clua.h" #include "delay.h" #include "dgnevent.h" #include "fight.h" @@ -2447,7 +2448,32 @@ std::string cloud_name(cloud_type type) } } -bool i_feel_safe(bool announce) +bool mons_is_safe(const struct monsters *mon, bool want_move) +{ + bool is_safe = mons_friendly(mon) || + (Options.safe_zero_exp && + mons_class_flag( mon->type, M_NO_EXP_GAIN )); + +#ifdef CLUA_BINDINGS + bool moving = ((!you.delay_queue.empty() && + is_run_delay(you.delay_queue.front().type) && + you.delay_queue.front().type != DELAY_REST) || + you.running < RMODE_NOT_RUNNING || want_move); + + int dist = grid_distance(you.x_pos, you.y_pos, + mon->x, mon->y); + bool result = is_safe; + + if (clua.callfn("ch_mon_is_safe", "Mbbd>b", + mon, is_safe, moving, dist, + &result)) + is_safe = result; +#endif + + return is_safe; +} + +bool i_feel_safe(bool announce, bool want_move) { /* This is probably unnecessary, but I'm not sure that you're always at least 9 away from a wall */ @@ -2486,12 +2512,10 @@ bool i_feel_safe(bool announce) if ( targ_monst != NON_MONSTER ) { const monsters *mon = &menv[targ_monst]; - if ( !mons_friendly(mon) && - player_monster_visible(mon) && + if ( player_monster_visible(mon) && !mons_is_submerged(mon) && !mons_is_mimic(mon->type) && - (!Options.safe_zero_exp || - !mons_class_flag( mon->type, M_NO_EXP_GAIN ))) + !mons_is_safe(mon, want_move)) { if (announce) mons.push_back(mon); diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h index c517b4c0d4..a0dc140417 100644 --- a/crawl-ref/source/misc.h +++ b/crawl-ref/source/misc.h @@ -169,7 +169,8 @@ const char *grid_item_destruction_message( dungeon_feature_type grid ); void curare_hits_player(int agent, int degree); -bool i_feel_safe(bool announce = false); +bool mons_is_safe(const struct monsters *mon, bool want_move = false); +bool i_feel_safe(bool announce = false, bool want_move = false); void setup_environment_effects(); diff --git a/crawl-ref/source/monspeak.cc b/crawl-ref/source/monspeak.cc index 267bab53e6..b79a7f9aec 100644 --- a/crawl-ref/source/monspeak.cc +++ b/crawl-ref/source/monspeak.cc @@ -856,7 +856,7 @@ bool mons_speaks(const monsters *monster) break; case 13: strcat(info, - " sighs, \"Being guard is usually so boring...\""); + " sighs, \"Being a guard is usually so boring...\""); break; case 14: strcat(info, " shouts, \"At last some action!\""); diff --git a/crawl-ref/source/notes.cc b/crawl-ref/source/notes.cc index ca74093ad0..6118d7c4e3 100644 --- a/crawl-ref/source/notes.cc +++ b/crawl-ref/source/notes.cc @@ -110,6 +110,7 @@ static bool is_noteworthy( const Note& note ) note.type == NOTE_USER_NOTE || note.type == NOTE_MESSAGE || note.type == NOTE_LOSE_GOD || + note.type == NOTE_PENANCE || note.type == NOTE_MOLLIFY_GOD || note.type == NOTE_DEATH ) return true; @@ -258,6 +259,10 @@ std::string Note::describe( bool when, bool where, bool what ) const result << "Fell from the grace of " << god_name(static_cast(first)); break; + case NOTE_PENANCE: + result << "Was placed under penance by " + << god_name(static_cast(first)); + break; case NOTE_MOLLIFY_GOD: result << "Was forgiven by " << god_name(static_cast(first)); diff --git a/crawl-ref/source/notes.h b/crawl-ref/source/notes.h index d0445ce827..ef4f794d05 100644 --- a/crawl-ref/source/notes.h +++ b/crawl-ref/source/notes.h @@ -38,6 +38,7 @@ enum NOTE_TYPES NOTE_USER_NOTE, /* needs: description string */ NOTE_MESSAGE, /* needs: message string */ NOTE_LOSE_GOD, /* needs: god id */ + NOTE_PENANCE, /* needs: god id */ NOTE_MOLLIFY_GOD, /* needs: god id */ NOTE_DEATH, /* needs: death cause */ NOTE_NUM_TYPES diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index fec05b1f76..db752f011d 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -344,10 +344,13 @@ void dec_penance(int val) void inc_penance(int god, int val) { - // orcish bonuses don't apply under penance - if ( god == GOD_BEOGH && you.penance[god] == 0) + if (you.penance[god] == 0 && val > 0) { - you.redraw_armour_class = 1; + take_note(Note(NOTE_PENANCE, god)); + + // orcish bonuses don't apply under penance + if (god == GOD_BEOGH) + you.redraw_armour_class = 1; } if (you.penance[god] + val > 200) diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc index 3eb0f53c5d..11eccfaac5 100644 --- a/crawl-ref/source/travel.cc +++ b/crawl-ref/source/travel.cc @@ -2204,7 +2204,7 @@ travel_target prompt_translevel_target(int prompt_flags) void start_translevel_travel(const travel_target &pos) { - if (!i_feel_safe(true)) + if (!i_feel_safe(true, true)) return; if (!can_travel_to(pos.p.id)) @@ -2235,7 +2235,7 @@ void start_translevel_travel(const travel_target &pos) void start_translevel_travel(bool prompt_for_destination) { - if (!i_feel_safe(true)) + if (!i_feel_safe(true, true)) return; // Update information for this level. We need it even for the prompts, so @@ -2592,7 +2592,7 @@ void start_travel(int x, int y) you.travel_x = x; you.travel_y = y; - if (!i_feel_safe(true)) + if (!i_feel_safe(true, true)) return; you.running.x = x; @@ -2622,7 +2622,7 @@ void start_explore(bool grab_items) return; } - if (!i_feel_safe(true)) + if (!i_feel_safe(true, true)) return; you.running = grab_items? RMODE_EXPLORE_GREEDY : RMODE_EXPLORE; diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index fd31a7edae..dd080ef687 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -907,17 +907,30 @@ void fire_monster_alerts() { if ((player_monster_visible(monster) || mons_was_seen_this_turn(monster)) - && !mons_is_submerged( monster ) - && !mons_friendly( monster )) + && !mons_is_submerged( monster )) { - if (!mons_class_flag( monster->type, M_NO_EXP_GAIN ) + if (!mons_is_safe( static_cast(monster) ) + && !mons_class_flag( monster->type, M_NO_EXP_GAIN ) && !mons_is_mimic( monster->type )) { interrupt_activity( AI_SEE_MONSTER, monster ); } seen_monster( monster ); + + // Monster was viewed this turn + monster->flags |= MF_WAS_IN_VIEW; + } + else + { + // Monster was not viewed this turn + monster->flags &= ~MF_WAS_IN_VIEW; } } + else + { + // Monster was not viewed this turn + monster->flags &= ~MF_WAS_IN_VIEW; + } } monsters_seen_this_turn.clear(); -- cgit v1.2.3-54-g00ecf