# TEAMCAPTAIN irum ##### Crawl Init file ############################################### # For descriptions of all options, as well as some more in-depth information # on setting them, consult the file # options_guide.txt # in your /docs directory. If you can't find it, the file is also available # online at: # https://github.com/crawl/crawl/blob/master/crawl-ref/docs/options_guide.txt # # Crawl uses the first file of the following list as its option file: # * init.txt in the -rcdir directory (if specified) # * .crawlrc in the -rcdir directory (if specified) # * init.txt (in the Crawl directory) # * ~/.crawl/init.txt (Unix only) # * ~/.crawlrc (Unix only) # * ~/init.txt (Unix only) # * settings/init.txt (in the Crawl directory) ##### Some basic explanation of option syntax ####################### # Lines beginning with '#' are comments. The basic syntax is: # # field = value or field.subfield = value # # Only one specification is allowed per line. # # The terms are typically case-insensitive except in the fairly obvious # cases (the character's name and specifying files or directories when # on a system that has case-sensitive filenames). # # White space is stripped from the beginning and end of the line, as # well as immediately before and after the '='. If the option allows # multiple comma/semicolon-separated terms (such as # autopickup_exceptions), all whitespace around the separator is also # trimmed. All other whitespace is left intact. # # There are three broad types of Crawl options: true/false values (booleans), # arbitrary values, and lists of values. The first two types use only the # simple =, with later options - which includes your options that are different # from the defaults - overriding earlier ones. List options allow using +=, ^=, # -=, and = to append, prepend, remove, and reset, respectively. Usually you will # want to use += to add to a list option. Lastly, there is := which you can use # to create an alias, like so: # ae := autopickup_exceptions # From there on, 'ae' will be treated as if it you typed autopickup_exceptions, # so you can save time typing it. # ##### Other files ################################################### # You can include other files from your options file using the 'include' # option. Crawl will treat it as if you copied the whole text of that file # into your options file in that spot. You can uncomment some of the following # lines by removing the beginning '#' to include some of the other files in # this folder. # Some useful, more advanced options, implemented in LUA. # include = advanced_optioneering.txt # Alternative vi bindings for Dvorak users. # include = dvorak_command_keys.txt # Alternative vi bindings for Colemak users. # include = colemak_command_keys.txt # Override the vi movement keys with a non-command. # include = no_vi_command_keys.txt # Turn the shift-vi keys into safe move, instead of run. # include = safe_move_shift.txt ##### Ancient versions ############################################## # If you're used to the interface of ancient versions of Crawl, you may # get back parts of it by uncommenting the following options: # include = 034_command_keys.txt # And to revert monster glyph and colouring changes: # include = 034_monster_glyphs.txt # include = 052_monster_glyphs.txt # include = 060_monster_glyphs.txt # include = 071_monster_glyphs.txt # include = 080_monster_glyphs.txt # include = 0.9_monster_glyphs.txt # include = 0.12_monster_glyphs.txt # include = 0.13_monster_glyphs.txt # include = 0.14_monster_glyphs.txt ##### 1- Starting Screen ############################################ # # name = Delilah # remember_name = false # weapon = (short sword | falchion | quarterstaff | hand axe | spear | mace # | trident | unarmed | random) # species = (Human |...| Vampire | random) # job = (Fighter |...| Wanderer | random) # random_pick = true # good_random = false # restart_after_game = true # default_manual_training = true ##### 2- File System ############################################### # # crawl_dir = # morgue_dir = morgue # save_dir = saves # macro_dir = settings/ # sound = : ##### 3- Interface ################################################# # ##### 3-a Picking up and Dropping ############### # # Rods are \ here. # autopickup = $?!:"/% # drop_filter += useless_item # default_autopickup = false # autopickup_no_burden = false # pickup_thrown = false # chunks_autopickup = false # assign_item_slot = (forward | backward) # # pickup_menu_limit = 1 # drop_filter += skeleton, corpse, useless_item ##### 3-b Targeting ############################ # # darken_beyond_range = false ##### 3-c Passive Sightings ##################### # # detected_monster_colour = lightred # detected_item_colour = green # remembered_monster_colour = darkgrey ##### 3-d Branding ############################## # # friend_brand = hi:green # neutral_brand = hi:lightgrey # stab_brand = hi:blue # may_stab_brand = hi:yellow # heap_brand = reverse # feature_item_brand = reverse # trap_item_brand = reverse ##### 3-e Level Map Functions ################### # # level_map_cursor_step = 7 # show_waypoints = false ##### 3-f Viewport Options ################### # # view_max_width = 33 # view_max_height = 21 # view_lock_x = false # view_lock_y = false # view_lock = false # center_on_scroll = true # symmetric_scroll = false # scroll_margin_x = 2 # scroll_margin_y = 2 # scroll_margin = 2 ##### 3-g Travel and Exploration ################# # # travel_delay = 20 (or -1 online) travel_delay = -1 # explore_delay = -1 # rest_delay = 0 (or -1 online) # travel_avoid_terrain = shallow water # # explore_greedy = false # explore_stop = items,stairs,shops,altars,portals,branches,runed_doors # explore_stop += greedy_pickup_smart,greedy_visited_item_stack # explore_stop += greedy_sacrificeable # sacrifice_before_explore = true # explore_improved = true # explore_wall_bias = 0 # travel_key_stop = false # auto_sacrifice = true # # explore_stop_pickup_ignore += curare # auto_exclude += oklob,statue,curse skull,roxanne,hyperactive,lightning spire # auto_exclude += mimic # tc_reachable = blue # tc_dangerous = cyan # tc_disconnected = darkgrey # tc_excluded = lightmagenta # tc_exclude_circle = red # Interrupting run and rest compound commands: # runrest_safe_poison = 80:100 # runrest_ignore_monster ^= butterfly:1 # runrest_ignore_monster ^= swamp worm:3 # runrest_stop_message += You hear a.* slurping noise # runrest_ignore_message += Jiyva's power touches on your attributes # A good number of runrest_messages are defined by default; you may want to # clear them or override some. # trapwalk_safe_hp = needle:15,arrow:35,bolt:45,spear:40,blade:95 #rest_wait_both = true ##### 3-h Command Enhancements ################## # # auto_switch = true # travel_open_doors = false # easy_unequip = false # equip_unequip = true # jewellery_prompt = true # easy_confirm = (none | safe | all) # allow_self_target = (yes | no | prompt) # confirm_butcher = (auto | always | never) # easy_eat_chunks = true # auto_eat_chunks = true # auto_drop_chunks = (never | rotten | yes) # prompt_for_swap = false # easy_quit_item_prompts = false # easy_exit_menu = true # sort_menus = pickup: true : art, ego, basename, qualname, curse, qty # sort_menus = inv: true : equipped, freshness, charged # autofight_stop = 30 # automagic_enable = false # automagic_fight = false # automagic_stop = 0 ##### 3-i Messages and Display Enhancements ##### # # hp_warning = 30 # mp_warning = 0 # hp_colour = 50:yellow, 25:red # mp_colour = 50:yellow, 25:red # stat_colour = 1:lightred, 3:red # status_caption_colour = yellow # clear_messages = true # small_more = true # show_more = false # show_newturn_mark = false # show_game_turns = false # item_stack_summary_minimum = 4 # mlist_min_height = 4 # mlist_allow_alternate_layout = true # mlist_targeting = true # msg_min_height = 7 # msg_max_height = 10 # messages_at_top = true # msg_condense_repeats = false # msg_condense_short = false # skill_focus = false # show_travel_trail = false (true for online) # view_delay = 600 # You can also enforce a --more-- prompt for messages ## Avoid wasting turns with aborted actions: # force_more_message += There are no visible monsters within range # force_more_message += This wand has no charges ##### 3-j Colours (messages and menus) ########## # # Items are colour coded by default as follows: # # yellow = useful escape item / preferred food # darkgrey = cannot be used # lightred = harmful / cursed and in use # magenta = dangerous to use / mutagenic # red = disliked by your deity # lightgreen = poisonous (food only) # brown = less nutritious (food only) # cyan = useful non-combat item # white = artefact # lightblue = unidentified magic item # # You can change colours by using something like # menu_colour ^= inventory:magenta:shillelagh # or ones in pick-up dialogs: # menu_colour ^= pickup:green:god gift # Colouring of messages # Messages are colour coded as follows: # # lightred = really important messages # yellow = significant messages # lightred = item damaged/destroyed # darkgrey = boring, message clutter # # Notes also use, quite misnamed, menu_colour: # menu_colour ^= notes:white:Reached XP level # These lines will suppress extra feedback messages from travel/shift-running. # # message_colour ^= mute:monster_warning: # message_colour ^= mute:You start resting # message_colour ^= mute:(HP|Magic) restored # message_colour ^= mute:warning:Not with.*(in view|monsters around) ##### 3-k Firing Commands ####################### # # fire_items_start = a # fire_order = launcher, return # fire_order += javelin / tomahawk / stone / rock / net # fire_order += inscribed ##### 3-l Channels ############################## # # channel.multiturn = mute ##### 3-m Inscriptions ########################## # # autoinscribe += bad_item.*potion:!q # autoinscribe += potion.*mutation:!q # autoinscribe_cursed = false # autoinscribe += fruit:!e # show_god_gift = yes|unident|no ##### 3-n Macro related Options ################# # # flush.failure = false # flush.command = true # flush.message = true ##### 3-o Tile related Options ################## # # tile_show_items = !?/%=([)x}:|\ # tile_skip_title = true # tile_menu_icons = false ### The following lines define the colours of various objects within the ### tiles minimap. See options_guide.txt for more details. # tile_player_col = white # tile_monster_col = #660000 # tile_neutral_col = #660000 # tile_peaceful_col = #664400 # tile_friendly_col = #664400 # tile_plant_col = #446633 # tile_item_col = #005544 # tile_unseen_col = black # tile_floor_col = #333333 # tile_wall_col = #666666 # tile_mapped_floor_col = #222266 # tile_mapped_wall_col = #444499 # tile_door_col = #775544 # tile_downstairs_col = #ff00ff # tile_upstairs_col = cyan # tile_branchstairs_col = #ff7788 # tile_portal_col = #ffdd00 # tile_feature_col = #997700 # tile_trap_col = #aa6644 # tile_water_col = #114455 # tile_deep_water_col = #001122 # tile_lava_col = #552211 # tile_excluded_col = #552266 # tile_excl_centre_col = #552266 # tile_window_col = #558855 # If Crawl's response rate is too slow, try increasing the update rate. # tile_update_rate = 1000 # If Crawl is lagging when running or resting, try increasing this number. # tile_runrest_rate = 100 # tile_key_repeat_delay = 200 # tile_tooltip_ms = 500 # tile_tag_pref = enemy ### Note: setting window, map or font sizes to '0' implies auto-sizing. # tile_full_screen = true # tile_window_width = 1024 # tile_window_height = 768 # tile_use_small_layout = true # tile_map_pixels = 3 # tile_cell_pixels = 32 # tile_filter_scaling = true # tile_force_overlay = true # tile_layout_priority = minimap, inventory, gold_turn, command, spell # tile_layout_priority += ability, monster # tile_font_crt_file = VeraMono.ttf # tile_font_stat_file = VeraMono.ttf # tile_font_msg_file = VeraMono.ttf # tile_font_tip_file = VeraMono.ttf # tile_font_lbl_file = Vera.ttf # tile_font_ft_light = false # tile_font_crt_size = 15 # tile_font_stat_size = 16 # tile_font_msg_size = 14 # tile_font_tip_size = 15 # tile_font_lbl_size = 14 # tile_show_minihealthbar = false # tile_show_minimagicbar = false # tile_show_demon_tier = false # tile_water_anim = false # tile_misc_anim = false ### WebTiles only # tile_font_crt_family = monospace # tile_font_stat_family = monospace # tile_font_msg_family = monospace # tile_font_lbl_family = monospace # tile_realtime_anim = true # tile_display_mode = glyph # tile_level_map_hide_messages = false # tile_level_map_hide_sidebar = true ##### 4- Dump File ################################################# # ##### 4-a Saving ################################ # # dump_on_save = false ##### 4-b Items and Kill List ################### # # kill_map = friend:you, other:you # dump_kill_places = (single | all | none) # dump_kill_breakdowns = true # dump_item_origins = all,artifacts,ego_arm,ego_weap,jewellery,runes # dump_item_origin_price = -1 # dump_message_count = 20 # dump_order = header, hiscore, stats, misc, notes, inventory, # dump_order += turns_by_place, skills, spells, overview, mutations, # dump_order += messages, screenshot, monlist, kills_by_place, kills # dump_order += action_counts # dump_book_spells = false ##### 4-c Notes ################################# # # user_note_prefix=@@@ # note_hp_percent = 5 # note_skill_levels = 1,5,10,15,27 # note_all_skill_levels = true # note_skill_max = false # note_xom_effects = false # note_chat_messages = false # note_items += rod of, acquirement, running, of Zot # note_monsters += orb of fire, ancient lich, Sigmund ##### 5- Miscellaneous ############################################# # ##### 5-a All OS ################################ # # mouse_input = true # wiz_mode = no # char_set = ascii # use_fake_player_cursor = false # # Translation to use (descriptions only for now). # language = pl|fr|zh|ko|fi|ru|el|da|li|pt|de|lv|cs|hu # # Joke translations (complete!). # language = dwarven|jagerkin|kraut|runes|wide|grunt # # colour.lightgray = black # colour.lightcyan = cyan # colour.yellow = brown # # show_player_species = true # See options_guide.txt for the options # cset, feature, mon_glyph, item_glyph ## Highlight the edge of unexplored terrain. # feature = explore horizon {',,green} ##### 5-b Windows console ####################### # # dos_use_background_intensity = true # background = black ##### 5-c Unix console ########################## # # use_fake_cursor = false ##### 5-d Alternative keybinding files ########## # # Alternative vi bindings for Dvorak users. # include = dvorak_command_keys.txt # # Alternative vi bindings for Colemak users. # include = colemak_command_keys.txt # # Override the vi movement keys with a non-command. # include = no_vi_command_keys.txt { function ready() speedrun_rest() end } { ----------------------------- ---- Begin speedrun_rest ---- ----------------------------- -- See README.md for documentation -- How many turns to rest at max. num_rest_turns = 20 -- If true, look for a foot item inventory slot and use fallback_slot if we -- can't find a ration. If false, always use fallback_slot. automatic_slot = true -- Slot where you keep your slow swing item. fallback_slot = "c" -- Set to true to have Na characters always walk instead of item swing if -- they're able to walk slowly. This is not as turncount efficient for non-Chei -- worshipers, but the difference is small and some Na players may prefer it -- over having to change the wielded weapon. naga_always_walk = false -- Delay in milliseconds before sending the next walk command. Makes the -- visuals a bit less jarring when using walk resting. Set to 0 to disable. walk_delay = 50 -- To have the multi-turn rest ignore status change messages, add an entry here -- giving the pattern of the message you'd like to ignore. The entries below -- cover the transition messages from the regen spell, Trog's hand, and poison -- status. The key should be the status that's seen in the output of -- `you.status()` when the status is active, and the value should be a single -- pattern string or an array of pattern strings matching the message you'd -- like to ignore. See the lua string library manual for details on making -- patterns. status_messages = { ["poisoned"] = {"You feel[^%.]+sick%.", "You are no longer poisoned%."}, ["regenerating"] = {"You feel the effects of Trog's Hand fading%.", "Your skin is crawling a little less now%."} } --end status_messages -- Like status_messages above, but for arbitrary messages. Any message matching -- one of these patterns is ignored. ignore_messages = { --RandomTiles messages "Trog roars: Now[^!]+!+", "Sif Muna whispers: Become[^!]+!+", "[^:]+ says: Become[^!]+!+", --Debug messages "Dbg:.*", } -- end ignore_messages -- NOTE: No configuration past this point. ATT_NEUTRAL = 1 version = 0.15 if crawl.version then version = tonumber(crawl.version("major")) end los_range = version >= 0.17 and 7 or 8 -- Wrapper of crawl.mpr() that prints text in white by default. if not mpr then mpr = function (msg, color) if not color then color = "white" end crawl.mpr("<" .. color .. ">" .. msg .. "") end end function control(c) return string.char(string.byte(c) - string.byte('a') + 1) end function delta_to_vi(dx, dy) local d2v = { [-1] = { [-1] = 'y', [0] = 'h', [1] = 'b'}, [0] = { [-1] = 'k', [1] = 'j'}, [1] = { [-1] = 'u', [0] = 'l', [1] = 'n'}, } -- hack return d2v[dx][dy] end function reset_rest() -- Clear out the now-unused persistant table in old versions if c_persist.bread then c_persist.bread = nil end if not rstate then rstate = { } rstate.set_slot = false rstate.dir_x = nil rstate.dir_y = nil end rstate.last_acted = nil rstate.wielding = false rstate.resting = false rstate.num_turns = nil rstate.rest_start = nil rstate.start_hp = nil rstate.start_status = { } rstate.start_message = nil end function abort_rest(msg) if msg then mpr(msg, "lightred") end reset_rest() end function crawl_message(i) local msg = crawl.messages(i):gsub("\n", "") msg = msg:gsub("^%c* *", "") msg = msg:gsub(" *%c*?$", "") return msg end function record_status() -- Record starting status to track any status changes. rstate.start_status = { } local status = you.status() for s,_ in pairs(status_messages) do if status:find(s) then rstate.start_status[s] = true end end rstate.start_message = get_last_message() end function in_water() return view.feature_at(0, 0):find("water") and not you.status("flying") end function get_last_message() local rest_type = get_rest_type() local in_water = in_water() -- Ignore these movement messages when walking. local move_patterns = {"There is a[^%.]+here.", "Things that are here:.*", "Items here:.*"} for i = 1,200 do local msg = crawl_message(i) for s,_ in pairs(rstate.start_status) do if type(status_messages[s]) == "table" then for _,p in ipairs(status_messages[s]) do msg = msg:gsub(p, "") end else msg = msg:gsub(status_messages[s], "") end end if rest_type == "walk" then for _,p in ipairs(move_patterns) do -- Also remove any whitespace. msg = msg:gsub(" *" .. p .. " *", "") end end msg = msg:gsub(" *Beep! [^%.]+%. *", "") for _,p in ipairs(ignore_messages) do msg = msg:gsub(p, "") end if msg ~= "" then return msg end end return nil end function wield_swing_item() rstate.wielding = true rstate.last_acted = you.turns() record_status() crawl.sendkeys("w" .. c_persist.swing_slot) end function find_swing_slot() rstate.set_slot = true if not automatic_slot then c_persist.swing_slot = fallback_slot return end c_persist.swing_slot = nil for _,item in ipairs(items.inventory()) do if item.class() == "Comestibles" then c_persist.swing_slot = items.index_to_letter(item.slot) break end end if not c_persist.swing_slot then c_persist.swing_slot = fallback_slot end end function swing_item_wielded() local weapon = items.equipped_at("Weapon") return weapon and weapon.slot == items.letter_to_index(c_persist.swing_slot) end function hostile_in_los() local have_t1 = false for x = -los_range,los_range do for y = -los_range,los_range do m = monster.get_monster_at(x, y) if m and not m:is_safe() then return true end end end return false end function ponderous_level() local level = 0 for _,item in ipairs(items.inventory()) do local ego = item.ego() if item.equipped and ego == "ponderousness" then level = level + 1 end end return level end -- XXX See if we can move at least some of this into clua, since it's -- recreating play_movement_speed() and player_speed(). The aim is to determine -- if slow move is more regen-efficient and that the saving is worth the -- hassle, this calculates the minimum move speed, which can normally vary at -- random from randomized delay (e.g. water) and the many uses of -- div_rand_round(). function player_move_speed() if you.transform() == "tree" then return 0 end local in_water = in_water() local walk_water = you.race() == "Merfolk" or you.race() == "Octopode" or you.god() == "Beogh" and you.piety_rank() == 5 or you.transform == "ice" -- This is player action speed, based on things that affect all actions. local player_speed = 10 if you.status("slowed") then player_speed = math.floor(player_speed * 3 / 2) end if you.status("berserking") and you.god() ~= "Cheibriados" or you.status("hasted") then player_speed = math.floor(player_speed * 2 / 3) end if you.transform() == "statue" or you.status("petrifying") then player_speed = math.floor(player_speed * 3 / 2) end if in_water and not walk_water then player_speed = math.floor(player_speed * 13 / 10) end -- This is the base player movement speed given all things that affect only -- movement. local move_speed = 10 if you.transform() == "bat" then move_speed = 5 elseif you.transform() == "pig" then move_speed = 7 elseif you.transform() == "porcupine" or you.transform == "wisp" then move_speed = 8 elseif in_water and (you.transform() == "hydra" or you.race() == "Merfolk") then move_speed = 6 elseif you.race() == "Tengu" and you.status("flying") then move_speed = 9 end local boots = items.equipped_at("Boots") local running_level = 0 if boots and not boots.is_melded and boots.ego() and boots.ego() == "running" then running_level = 1 end move_speed = move_speed - running_level move_speed = move_speed + ponderous_level() if you.god() == "Cheibriados" then -- Calculate this based on the minimum piety at the observed rank, -- since we can't know the true piety level. local piety_breaks = { 1, 30, 50, 75, 100, 120, 160 } move_speed = move_speed + 2 + math.floor(math.min(piety_breaks[you.piety_rank() + 1] / 20, 8)) end if you.status("frozen") then move_speed = move_speed + 4 end if you.status("grasped by roots") then move_speed = move_speed + 3 end local speed_mut = you.mutation("speed") local slow_mut = you.mutation("slowness") if speed_mut > 0 then move_speed = move_speed - speed_mut - 1 elseif slow_mut > 0 then move_speed = math.floor(move_speed * (10 + slow_mut * 2) / 10) end if not in_water and you.status("sluggish") then if move_speed >= 8 then move_speed = math.floor(move_speed * 3 / 2) elseif move_speed == 7 then move_speed = math.floor(7 * 6 / 5) end elseif not in_water and you.status("swift") then move_speed = math.floor(move_speed * 3 / 4) end if move_speed < 6 then move_speed = 6 end return math.floor(player_speed * move_speed / 10) end function get_rest_type() if you.race() == "Naga" and naga_always_walk or you.god() == "Cheibriados" or not weapon_can_swap() then return "walk" else return "item" end end function bad_to_act() local hp, mhp = you.hp() local rest_type = get_rest_type() -- Stop multiple turn action when our hp recovers. if rstate.rest_start and rstate.start_hp < mhp and hp == mhp then mpr("HP restored.") reset_rest() return true end if you.status("manticore barbs") then abort_rest("You must remove the manticore barbs first.") return true end if you.hunger_name() == "fainting" or you.hunger_name() == "starving" then abort_rest("You need to eat!") return true end if hostile_in_los() then if not rstate.rest_start then abort_rest("You can't rest with a hostile monster in view!") else abort_rest() end return true end -- If any unrecognized message occurs, assume we need to stop resting. if rstate.last_acted then local msg = get_last_message() if not msg then abort_rest("Unable to find a previous message!") return true end local wield_pt = "^ *" .. c_persist.swing_slot .. " - .+[%)}] *$" local swing_pt = "^ *You swing at nothing%. *$" local pattern = rstate.wielding and wield_pt or swing_pt if (rest_type == "item" and not msg:find(pattern)) or rest_type == "walk" and msg ~= rstate.start_message then abort_rest() return true end end if rest_type == "walk" and player_move_speed() <= 10 then abort_rest("You cannot walk slowly right now!") return true end return false end function feat_is_open(feat) local fname = feat:lower() -- Unique substrings that identify solid features. local solid_features = {"wall", "grate", "tree", "mangrove", "endless_lava", "open_sea", "statue", "idol", "malign_gateway", "sealed_door", "closed_door", "runed_door", "explore_horizon"} for i,p in ipairs(solid_features) do if fname:find(p) then return false end end return true end function safe_walk_pos(x, y) local in_water = in_water() local pos_is_water = view.feature_at(x, y):find("water") -- Don't allow walking out of water if we're in water return (in_water and pos_is_water -- Don't allow walking into water if we're not in it or not in_water and not pos_is_water) -- Require the destination to be safe. and view.is_safe_square(x, y) end function safe_swing_pos(x, y) return not monster.get_monster_at(x, y) and feat_is_open(view.feature_at(x,y)) end function safe_direction(x, y) if get_rest_type() == "walk" then return safe_walk_pos(x, y) else return safe_swing_pos(x, y) end end function weapon_can_swap() local weapon = items.equipped_at("Weapon") if not weapon then return true end if weapon.cursed then return false end local ego = weapon.ego() -- Some unrands like Plut. sword have no ego. if ego and (ego == "vampirism" or ego == "distortion" and you.god() ~= "Lugonu") then return false end if weapon.artefact then local artp = weapon.artprops return not (artp["*Contam"] or artp["*Curse"] or artp["*Drain"]) end return true end function get_safe_direction() local have_t1 = false for x = -1,1 do for y = -1,1 do if (x ~= 0 or y ~= 0) and safe_direction(x, y) then return x, y end end end return nil end function do_resting() -- Our first turn of resting. if not rstate.rest_start then record_status() rstate.rest_start = you.turns() rstate.start_hp = you.hp() end rstate.last_acted = you.turns() local rest_type = get_rest_type() if rest_type == "item" then crawl.sendkeys(control(delta_to_vi(rstate.dir_x, rstate.dir_y))) else local cur_x = rstate.dir_x local cur_y = rstate.dir_y -- Save the return direction as our next direction. rstate.dir_x = -rstate.dir_x rstate.dir_y = -rstate.dir_y crawl.sendkeys(delta_to_vi(cur_x, cur_y)) crawl.delay(walk_delay) end end function one_turn_rest() rstate.resting = true rstate.num_turns = 1 end function start_resting() rstate.resting = true rstate.num_turns = num_rest_turns end function set_swing_slot() crawl.formatted_mpr("Enter an slot letter for the swing item: ", "prompt") local letter = crawl.c_input_line() local index = items.letter_to_index(letter) if not index or index < 0 then mpr("Must be a letter (a-z or A-Z)!", "lightred") return end c_persist.swing_slot = letter rstate.set_slot = true mpr("Set swing slot to " .. letter .. ".") end function speedrun_rest() local rest_type = get_rest_type() if rest_type == "item" and (not c_persist.swing_slot or you.turns() == 0 and not rstate.set_slot) then find_swing_slot() end if not rstate.resting then return end -- Only act once per turn. if rstate.last_acted == you.turns() then -- An error happened with the 'w' command if rstate.wielding and not swing_item_wielded() then abort_rest("Unable to wield swing item on slot " .. c_persist.swing_slot .. "!") end return end if rstate.last_acted and rstate.rest_start and rstate.last_acted + 1 >= rstate.rest_start + rstate.num_turns then reset_rest() return end if bad_to_act() then return end if rest_type == "item" and not swing_item_wielded() then wield_swing_item() return end rstate.wielding = false if not rstate.dir_x -- Don't try to reuse our position if we were walk resting and did -- something inbetween our last rest. or swing_type == "walk" and rstat.last_acted ~= you.turns() - 1 or not safe_direction(rstate.dir_x, rstate.dir_y) then rstate.dir_x, rstate.dir_y = get_safe_direction() if not rstate.dir_x then abort_rest("No safe direction found!") return end end do_resting() end reset_rest() --------------------------- ---- End speedrun_rest ---- --------------------------- }