Some helpful RC snippits

Some of this I’ve shared in other topics but I wanted to put, especially the Lua code, in a single post.

Basic

Most crawl veterans already know about these but worth pointing out for new players.

# Start with manual training instead of autotraining
# Even better if you use the related code snippet in the Lua section ready() function
default_manual_training = true

# Stop tabbing at 69% hp. 
# Default is 50. Configure your own balance of safety and convenience
autofight_stop = 69

# Make resting instant instead of showing you game updates slowly
# Travel and explore delay are more to taste but it does speed up the game
rest_delay = -1
travel_delay = -1
explore_delay = -1
# Show the path you auto-traveled so you don't get disoriented
show_travel_trail = true

Keybinds

# Open the lua command console with ~
bindkey = [~] CMD_LUA_CONSOLE

# bind < and > to left and right arrow keys, in the menu context only
# Nice if you use vi keys
macros += K4 > \{-251}
macros += K4 < \{-252}

# Don't use quiver with autofight_nomove, which we bind to shift+tab
# Now you can hold shift+tab to melee without moving or using quiver
# When a gap is created instead of stepping into the gap, the command does nothing
# By default shift+tab fires your quiver but p also does this by default so it's fine to rebind
# If you want to continue using shift+tab for your quiver, bindkey to something else.
autofight_nomove_fires = false
bindkey = [\{-233}] CMD_AUTOFIGHT_NOMOVE

Spell keybinds

I ran all the spells through a script. Try to bind spells with either the first letter of one of their words or, if that’s already taken, the first available consonant. If all consonants are taken it will use X Y or Z.

Some spells are capitalized at my whim.

It’s bad form to put duplicate letters for the same spell here but it won’t hurt and I didn’t bother scripting their removal :stuck_out_tongue:

I’m a vi-keys user so all letters are more-or-less convenient to use with spells. If these don’t work for you, you can at least use this as a template.

Click here to show spell slot bindings
spell_slot += Airstrike:arstrk
spell_slot += Alistair's Intoxication:ailstrsntxctn
spell_slot += Alistair's Walking Alembic:awalstrslknglmbc
spell_slot += Anguish:angsh
spell_slot += Animate Dead:adnmtd
spell_slot += Apportation:apprttn
spell_slot += Arcjolt:arcjlt
spell_slot += Awaken Armour:aawknrmr
spell_slot += Blink:blnk
spell_slot += Bombard:bmbrd
spell_slot += Borgnjor's Revivification:BRRGNJRSVVFCTN
spell_slot += Borgnjor's Vile Clutch:bvcrgnjrslltch
spell_slot += Brom's Barrelling Boulder:bbbrmsrrllngldr
spell_slot += Call Canine Familiar:cfnnmlr
spell_slot += Call Imp:imp
spell_slot += Cause Fear:cfsr
spell_slot += Chain Lightning:CLHNGHTNNG
spell_slot += Cigotuvi's Putrefaction:cpgtvstrfctn
spell_slot += Confusing Touch:CTNFSNGCH
spell_slot += Conjure Ball Lightning:cblnjrllghtnng
spell_slot += Construct Spike Launcher:cslnstrctpknchr
spell_slot += Curse of Agony:carsgny
spell_slot += Death Channel:dcthhnnl
spell_slot += Death's Door:ddthsr
spell_slot += Detonation Catalyst:dctntntlyst
spell_slot += Diamond Sawblades:dsmndwblds
spell_slot += Dimensional Bullseye:dbmnsnlllsy
spell_slot += Discord:dscrd
spell_slot += Disjunction:dsjnctn
spell_slot += Dispel Undead:dusplndd
spell_slot += Dispersal:dsprsl
spell_slot += Dragon's Call:DRGNS
spell_slot += Enfeeble:enfbl
spell_slot += Ensorcelled Hibernation:ehnsrclldbrntn
spell_slot += Eringya's Noxious Bog:enbrngysxsg
spell_slot += Eringya's Surprising Crocodile:escrngysrprsngrcdl
spell_slot += Fire Storm:fsrtrm
spell_slot += Fireball:frbll
spell_slot += Flame Wave:fwlmv
spell_slot += Forge Blazeheart Golem:bglzhrtlm
spell_slot += Forge Lightning Spire:lsghtnngpr
spell_slot += Forge Monarch Bomb:mbnrchmb
spell_slot += Forge Phalanx Beetle:pbhlnxtl
spell_slot += Fortress Blast:fbrtrsslst
spell_slot += Foxfire:fxfr
spell_slot += Freeze:frz
spell_slot += Freezing Cloud:fcrzngld
spell_slot += Frozen Ramparts:frrznmprts
spell_slot += Fugue of the Fallen:ffglln
spell_slot += Fulminant Prism:fplmnntrsm
spell_slot += Fulsome Fusillade:fflsmslld
spell_slot += Gell's Gavotte:ggllsvtt
spell_slot += Gloom:glm
spell_slot += Grave Claw:gcrvlw
spell_slot += Hailstorm:hlstrm
spell_slot += Haunt:hnt
spell_slot += Hellfire Mortar:hmllfrrtr
spell_slot += Hoarfrost Cannonade:hcrfrstnnnd
spell_slot += Ignite Poison:ipgntsn
spell_slot += Ignition:igntn
spell_slot += Infestation:infsttn
spell_slot += Inner Flame:ifnnrlm
spell_slot += Irradiate:irrdt
spell_slot += Iskenderun's Battlesphere:bttlsphr
spell_slot += Iskenderun's Mystic Blast:mbystclst
spell_slot += Jinxbite:jnxbt
spell_slot += Kinetic Grapnel:kgntcrpnl
spell_slot += Kiss of Death:kdssth
spell_slot += Launch Clockwork Bee:lcbnchlckwrk
spell_slot += Leda's Liquefaction:lldsqfctn
spell_slot += Lee's Rapid Deconstruction:lrdspdcnstrctn
spell_slot += Lehudib's Crystal Spear:lcshdbsrystlpr
spell_slot += Lesser Beckoning:lbssrcknng
spell_slot += Magic Dart:mdgcrt
spell_slot += Magnavolt:mgnvlt
spell_slot += Malign Gateway:MGLGNTWY
spell_slot += Manifold Assault:manfldsslt
spell_slot += Martyr's Knell:mkrtyrsnll
spell_slot += Maxwell's Capacitive Coupling:MCCXWLLSPCTVPLNG
spell_slot += Maxwell's Portable Piledriver:mppxwllsrtblldrvr
spell_slot += Mephitic Cloud:mcphtcld
spell_slot += Mercury Arrow:marcryrrw
spell_slot += Metabolic Englaciation:metblcnglctn
spell_slot += Momentum Strike:msmntmtrk
spell_slot += Nazja's Percussive Tempering:nptzjsrcssvmprng
spell_slot += Olgreb's Toxic Radiance:otrlgrbsxcdnc
spell_slot += Orb of Destruction:odrbstrctn
spell_slot += Ozocubu's Armour:oazcbsrmr
spell_slot += Ozocubu's Refrigeration:orzcbsfrgrtn
spell_slot += Passage of Golubria:pgssglbr
spell_slot += Passwall:psswll
spell_slot += Permafrost Eruption:permfrstrptn
spell_slot += Petrify:ptrfy
spell_slot += Plasma Beam:pblsmm
spell_slot += Platinum Paragon:ppltnmrgn
spell_slot += Poisonous Vapours:pvsnsprs
spell_slot += Polar Vortex:PVLRRTX
spell_slot += Rending Blade:rbndngld
spell_slot += Rimeblight:rmblght
spell_slot += Sandblast:sndblst
spell_slot += Scorch:scrch
spell_slot += Sculpt Simulacrum:ssclptmlcrm
spell_slot += Searing Ray:srrngy
spell_slot += Shatter:shttr
spell_slot += Shock:shck
spell_slot += Sigil of Binding:sbglndng
spell_slot += Silence:slnc
spell_slot += Slow:slw
spell_slot += Soul Splinter:sslplntr
spell_slot += Spellspark Servitor:sspllsprkrvtr
spell_slot += Sphinx Sisters:ssphnxstrs
spell_slot += Splinterfrost Shell:ssplntrfrsthll
spell_slot += Starburst:strbrst
spell_slot += Static Discharge:sdttcschrg
spell_slot += Sticky Flame:sftckylm
spell_slot += Stone Arrow:satnrrw
spell_slot += Sublimation of Blood:sbblmtnld
spell_slot += Summon Cactus Giant:cgctsnt
spell_slot += Summon Forest:frst
spell_slot += Summon Horrible Things:htrrblhngs
spell_slot += Summon Hydra:hydr
spell_slot += Summon Ice Beast:ibcst
spell_slot += Summon Mana Viper:mvnpr
spell_slot += Summon Seismosaurus Egg:sesmsrsgg
spell_slot += Summon Small Mammal:smmllmml
spell_slot += Swiftness:SWFTNSS
spell_slot += Teleport Other:tolprtthr
spell_slot += Tukima's Dance:tdkmsnc
spell_slot += Vampiric Draining:vdmprcrnng
spell_slot += Vhi's Electric Charge:vechslctrchrg
spell_slot += Volatile Blastmotes:vbltllstmts
spell_slot += Yara's Violent Unravelling:yvurslntnrvllng

# Default letters
spell_slot += .*:XYZ

Lua

Many things can be scripted with Lua. See the documentation here: Crawl Lua API

Important:

  1. You need to mark your Lua code so that the game knows it’s Lua. Simply put it between curly braces { }, such as the ones at the very top and bottom of the code block below.
  2. Most of these require a hook in the ready() function so don’t ignore the ready() function at the bottom!
Click here for Lua goodies
{
   ---------------------------------
   --- Utility                   ---
   ---------------------------------

function getOrDefault(table, key, default)
  if table[key] ~= nil
    then return table[key]
    else return default
  end
end

   ---------------------------------
   --- Vaults 5 Stairs Warning   ---
   ---------------------------------

-- Automatically add an annotation to V5 so you don't go down by accident
-- Make sure to include  "annotate_v5()" in your ready function or this won't work


-- check to see if "annotated_v5" was already initialized by chk_lua_save
-- If it was we need to make sure it's added to chk_lua_save again
if annotated_v5 ~= true 
then annotated_v5 = false 
else table.insert(chk_lua_save, function () return "annotated_v5 = true" end)
end


function annotate_v5()
  if (not annotated_v5) and (you.branch() == "Vaults") then
    crawl.sendkeys("!v5" .. string.char(13) .. "!vaults warning" .. string.char(13))
    annotated_v5 = true
    -- also set this to true anytime this save is loaded
    table.insert(chk_lua_save, function () return "annotated_v5 = true" end)
  end
end

   ---------------------------------
   --- HP Warnings & Notes       ---
   ---------------------------------

-- Print a message and take note when hp goes above or below a certain ratio
-- "force_more_message += it's so over" will pause the game when at low hp
-- Must include "evaluate_wellbeing()" in your ready() function or this won't work

-- Set these two variables as desired 
-- (currently warning at 30% and celebration at 70%)
itsoverratio = .30
werebackratio = .70

function hp_ratio()
  hp, mhp = you.hp()
  return hp / mhp
end

itsover = hp_ratio() <= itsoverratio -- initializing this in case save is loaded at low hp
function evaluate_wellbeing()
  if itsover and hp_ratio() >= werebackratio then
    crawl.take_note("We're so back!")
    crawl.mpr("we're so back!")
    itsover = false
  elseif not itsover and hp_ratio() <= itsoverratio then
    hp, mhp = you.hp()
    crawl.take_note(string.format("It's so over! %d/%d", hp, mhp))
    crawl.mpr("it's so over!")
    itsover = true
  end
end

   ---------------------------------
   --- Felid Lives-based Tile    ---
   ---------------------------------

-- change felid tile based on number of lives left
-- Must include "update_felid_tile()" in your ready() function or this won't work

-- see https://github.com/crawl/crawl/tree/master/crawl-ref/source/rltiles/player/felids for felid tiles
-- below is how file names map to tile names.
-- for instance if you want the cat9.png file, you should use tile:felid_6
--cat1 felid
--cat2 felid_1
--cat4 felid_2
--cat5 felid_3
--cat7 felid_4
--cat8 felid_5
--cat9 felid_6
--cat3 felid_silly
--cat6 felid_silly_1
--cat10 felid_silly_2

felid_tiles = {"tile:felid_5", "tile:felid_silly", "mons:manticore"} -- 0 lives, 1 life, 2 lives
function update_felid_tile()
  if you.race() == "Felid" then
    crawl.setopt("tile_player_tile = " .. felid_tiles[you.lives() + 1])
  end
end

   ---------------------------------
   --- API Hook functions        ---
   ---------------------------------

-- Called when a message is logged
function c_message(text, channel)
  -- Note faded altar offerings
  if text:find("This altar belongs to") then
    a, b, c = text:match("%(a%) ([%w%s]+), %(b%) ([%w%s]+) or %(c%) ([%w%s]+),")
    crawl.take_note(string.format("Faded altar: %s, %s, %s", a, b, c))
  end
end

-- auto answer prompts that contain these patterns 
-- pass has priority over no, which has priority over yes
prompt_pass = {} -- answer these manually
prompt_no   = {}
prompt_yes  = {"arc blade's discharge", "freezing cloud near yourself"}
function c_answer_prompt(prompt)

  function found_any(text, patterns)
    return util.exists(
      patterns,
      function (patt) return text:find(patt) end
    )
  end

  if     found_any(prompt, prompt_pass) then return nil
  elseif found_any(prompt, prompt_no)   then return false
  elseif found_any(prompt, prompt_yes)  then return true
  end
end

-- Called when it is your turn to act
function ready()

  -- Open skill screen on turn 0. Useful with "default_manual_training = true"
  if not skills_set and you.turns() == 0 then
    crawl.sendkeys("m")
    skills_set = true
  end

  annotate_v5()

  evaluate_wellbeing()

  update_felid_tile()

end

}
5 Thanks