# vim: set ft=dcss-rc:
# enc=latin1
##### 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
# Alternative vi bindings for Neo users.
# include = neo_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
{
is_stoat_soup = string.find(crawl.version(), '%d+%.%d+-ish') ~= nil
is_bcrawl = string.find(crawl.version(), 'bcrawl-') ~= nil
is_bcadrencrawl = string.find(crawl.version(), '0.06.7.4-') ~= nil
}
###################### WIZMODE NOTES #######################
#
# &% to create an item with spec
#
# Example:
#
# the +11 sling of Uceiwk (weapon) {flame, Int+3 Dex+4}
# => sling plus:11 ego:flaming mundane artprops:int:3&dex:4
#
# the +6 morningstar of the Lamprey {freeze, rElec Int+2}
# => morningstar plus:6 ego:freezing mundane artprops:rElec:1&int:2
#
# the +3 long sword "Giantbane" {drain, rF- Will+ Dex+3}
# => long sword plus:3 ego:draining mundane artprops:rf:-1&will:1&dex:3
#
# a +2 pair of gloves of strength
# => pair of gloves plus:2 ego:strength
#
# the +11 demon trident of Viyrr {freeze, rF++}
# => demon trident plus:11 ego:freezing artprops:rf:2 mundane
#
# the ring "Kuhatin" {rElec rC+ Dex+4}
# => ring of protection from cold artprops:rElec:dex:4 mundane
#
# => any potion q:99 pre_id
#
# Just double-check that the item didn't create with more artprops than it should have.
#
############################################################
{
-- Convenience function. Be careful of shadowing/collisions.
function p(...)
local arg = {...}
for i = 1, #arg do
if arg[i] == nil then
arg[i] = 'nil'
else
local t = type(arg[i])
if t == 'table' then
arg[i] = json.stringify(arg[i])
elseif t ~= 'string' then
arg[i] = tostring(arg[i])
end
end
end
return crawl.mpr('> ' .. table.concat(arg, ', '))
end
}
{
function control(c)
return string.char(string.byte(c) - string.byte('a') + 1)
end
}
{
-- it = with_item('g', function(it); return it.damage_rating(); end)
function with_item(letter, fn)
local it = items.inslot(items.letter_to_index(letter))
if fn ~= nil then
crawl.mpr(string.format('> %s', fn(it)))
end
return it
end
function tostring_item(it)
if it ~= nil and type(it.name) == 'function' then
return string.format('%s %s %s',
it.slot and items.index_to_letter(it.slot) or '?',
it.equipped and '+' or '-',
it.name_coloured())
else
return tostring(it)
end
end
function dump_item(it)
if it ~= nil and type(it.name) == 'function' then
return string.format('%s %s %s (class(true)=%s, subtype(true)=%s, subtype(false)=%s, artefact=%s, branded=%s, ac=%s, plus=%s)',
it.slot and items.index_to_letter(it.slot) or '?',
it.equipped and '+' or '-',
it.name_coloured(),
it.class(true),
it.subtype(true),
it.subtype(false),
it.artefact,
it.branded,
it.ac,
it.plus)
end
end
function item_cur_atk_delay(it)
return string.match(tostring(it.description), 'Current attack delay: (%d+.%d+).')
end
}
{
-- https://gist.github.com/pocco81/9ee123862db531e439190209207beaa5
--[[ json.lua
A compact pure-Lua JSON library.
The main functions are: json.stringify, json.parse.
## json.stringify:
This expects the following to be true of any tables being encoded:
* They only have string or number keys. Number keys must be represented as
strings in json; this is part of the json spec.
* They are not recursive. Such a structure cannot be specified in json.
A Lua table is considered to be an array if and only if its set of keys is a
consecutive sequence of positive integers starting at 1. Arrays are encoded like
so: `[2, 3, false, "hi"]`. Any other type of Lua table is encoded as a json
object, encoded like so: `{"key1": 2, "key2": false}`.
Because the Lua nil value cannot be a key, and as a table value is considerd
equivalent to a missing key, there is no way to express the json "null" value in
a Lua table. The only way this will output "null" is if your entire input obj is
nil itself.
An empty Lua table, {}, could be considered either a json object or array -
it's an ambiguous edge case. We choose to treat this as an object as it is the
more general type.
To be clear, none of the above considerations is a limitation of this code.
Rather, it is what we get when we completely observe the json specification for
as arbitrary a Lua object as json is capable of expressing.
## json.parse:
This function parses json, with the exception that it does not pay attention to
\u-escaped unicode code points in strings.
It is difficult for Lua to return null as a value. In order to prevent the loss
of keys with a null value in a json string, this function uses the one-off
table value json.null (which is just an empty table) to indicate null values.
This way you can check if a value is null with the conditional
`val == json.null`.
If you have control over the data and are using Lua, I would recommend just
avoiding null values in your data to begin with.
--]]
-- local json = {}
json = {}
-- Internal functions.
local function kind_of(obj)
if type(obj) ~= 'table' then return type(obj) end
local i = 1
for _ in pairs(obj) do
if obj[i] ~= nil then i = i + 1 else return 'table' end
end
if i == 1 then return 'table' else return 'array' end
end
local function escape_str(s)
local in_char = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'}
local out_char = {'\\', '"', '/', 'b', 'f', 'n', 'r', 't'}
for i, c in ipairs(in_char) do
s = s:gsub(c, '\\' .. out_char[i])
end
return s
end
-- Returns pos, did_find; there are two cases:
-- 1. Delimiter found: pos = pos after leading space + delim; did_find = true.
-- 2. Delimiter not found: pos = pos after leading space; did_find = false.
-- This throws an error if err_if_missing is true and the delim is not found.
local function skip_delim(str, pos, delim, err_if_missing)
pos = pos + #str:match('^%s*', pos)
if str:sub(pos, pos) ~= delim then
if err_if_missing then
error('Expected ' .. delim .. ' near position ' .. pos)
end
return pos, false
end
return pos + 1, true
end
-- Expects the given pos to be the first character after the opening quote.
-- Returns val, pos; the returned pos is after the closing quote character.
local function parse_str_val(str, pos, val)
val = val or ''
local early_end_error = 'End of input found while parsing string.'
if pos > #str then error(early_end_error) end
local c = str:sub(pos, pos)
if c == '"' then return val, pos + 1 end
if c ~= '\\' then return parse_str_val(str, pos + 1, val .. c) end
-- We must have a \ character.
local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'}
local nextc = str:sub(pos + 1, pos + 1)
if not nextc then error(early_end_error) end
return parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc))
end
-- Returns val, pos; the returned pos is after the number's final character.
local function parse_num_val(str, pos)
local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos)
local val = tonumber(num_str)
if not val then error('Error parsing number at position ' .. pos .. '.') end
return val, pos + #num_str
end
-- Public values and functions.
function json.stringify(obj, as_key)
local s = {} -- We'll build the string as an array of strings to be concatenated.
local kind = kind_of(obj) -- This is 'array' if it's an array or type(obj) otherwise.
if kind == 'array' then
if as_key then error('Can\'t encode array as key.') end
s[#s + 1] = '['
for i, val in ipairs(obj) do
if i > 1 then s[#s + 1] = ', ' end
s[#s + 1] = json.stringify(val)
end
s[#s + 1] = ']'
elseif kind == 'table' then
if as_key then error('Can\'t encode table as key.') end
s[#s + 1] = '{'
for k, v in pairs(obj) do
if #s > 1 then s[#s + 1] = ', ' end
s[#s + 1] = json.stringify(k, true)
s[#s + 1] = ':'
s[#s + 1] = json.stringify(v)
end
s[#s + 1] = '}'
elseif kind == 'string' then
return '"' .. escape_str(obj) .. '"'
elseif kind == 'number' then
if as_key then return '"' .. tostring(obj) .. '"' end
return tostring(obj)
elseif kind == 'boolean' then
return tostring(obj)
elseif kind == 'nil' then
return 'null'
elseif kind == 'userdata' then
if type(obj.name_coloured) == 'function' then
return tostring_item(obj)
else
_debug = obj
return 'undefined'
end
else
-- error('Unjsonifiable type: ' .. kind .. '.')
_debug = obj
return 'undefined'
end
return table.concat(s)
end
json.null = {} -- This is a one-off table to represent the null value.
function json.parse(str, pos, end_delim)
pos = pos or 1
if pos > #str then error('Reached unexpected end of input.') end
local pos = pos + #str:match('^%s*', pos) -- Skip whitespace.
local first = str:sub(pos, pos)
if first == '{' then -- Parse an object.
local obj, key, delim_found = {}, true, true
pos = pos + 1
while true do
key, pos = json.parse(str, pos, '}')
if key == nil then return obj, pos end
if not delim_found then error('Comma missing between object items.') end
pos = skip_delim(str, pos, ':', true) -- true -> error if missing.
obj[key], pos = json.parse(str, pos)
pos, delim_found = skip_delim(str, pos, ',')
end
elseif first == '[' then -- Parse an array.
local arr, val, delim_found = {}, true, true
pos = pos + 1
while true do
val, pos = json.parse(str, pos, ']')
if val == nil then return arr, pos end
if not delim_found then error('Comma missing between array items.') end
arr[#arr + 1] = val
pos, delim_found = skip_delim(str, pos, ',')
end
elseif first == '"' then -- Parse a string.
return parse_str_val(str, pos + 1)
elseif first == '-' or first:match('%d') then -- Parse a number.
return parse_num_val(str, pos)
elseif first == end_delim then -- End of an object or array.
return nil, pos + 1
else -- Parse true, false, or null.
local literals = {['true'] = true, ['false'] = false, ['null'] = json.null}
for lit_str, lit_val in pairs(literals) do
local lit_end = pos + #lit_str - 1
if str:sub(pos, lit_end) == lit_str then return lit_val, lit_end + 1 end
end
local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10)
error('Invalid json syntax starting at ' .. pos_info_str)
end
end
-- return json
}
# https://crawl.dcss.io/crawl/rcfiles/crawl-git/dossy.rc.persist
{
-- ------------------------------------------------------------
-- SKILLS: BEGIN
-- ------------------------------------------------------------
Skills = {}
Skills.__index = function(tbl, key)
return rawget(tbl, key)
end
Skills = setmetatable(Skills, Skills)
Skills.loaded = false
Skills.key = you.race() .. "/" .. you.class()
Skills.names = {
"Fighting",
"Maces & Flails",
"Axes",
"Polearms",
"Staves",
"Unarmed Combat",
"Throwing",
"Short Blades",
"Long Blades",
"Ranged Weapons",
"Armour",
"Dodging",
"Shields",
"Stealth",
"Spellcasting",
"Conjurations",
"Hexes",
"Summonings",
"Necromancy",
"Forgecraft",
"Translocations",
"Alchemy",
"Fire Magic",
"Ice Magic",
"Air Magic",
"Earth Magic",
"Invocations",
"Evocations",
"Shapeshifting" }
Skills.skills = {}
for _, s in ipairs(Skills.names) do
Skills.skills[s] = { 0, 0.0 }
end
function Skills:read()
for _, s in ipairs(self.names) do
self.skills[s] = { you.train_skill(s), you.get_training_target(s) }
end
end
function Skills:write()
for _, s in ipairs(self.names) do
local status, target = table.unpack(self.skills[s])
you.train_skill(s, status)
you.set_training_target(s, target)
end
end
function Skills:__tostring(all)
local results = {}
local glyphs = { [0] = "-", [1] = "+", [2] = "*" }
for _, s in ipairs(self.names) do
local state, target = table.unpack(self.skills[s])
if all or (state > 0 or target > 0) then
local str = glyphs[state] .. " " .. s
if target > 0 then
str = str .. " (" .. target .. ")"
end
table.insert(results, str)
end
end
return table.concat(results, "; ")
end
function Skills:exists()
return c_persist.char_defaults ~= nil
and c_persist.char_defaults[self.key] ~= nil
end
function Skills:save()
self:read()
if not c_persist.char_defaults then
c_persist.char_defaults = {}
end
local value = {}
for _, s in ipairs(self.names) do
local state, target = table.unpack(self.skills[s])
if state > 0 or target > 0 then
value[s] = self.skills[s]
end
end
c_persist.char_defaults[self.key] = value
end
function Skills:load()
if self:exists() then
local values = c_persist.char_defaults[self.key]
for _, s in ipairs(self.names) do
if values[s] then
self.skills[s] = values[s]
else
self.skills[s] = { 0, 0 }
end
end
self:write()
end
self.loaded = true
end
function Skills:init()
if you.turns() ~= 0 then
return
end
if not Skills.loaded then
Skills:load()
if you.race() ~= 'Gnoll' and not Skills:exists() then
crawl.sendkeys("m")
end
end
end
Skills:init()
-- ------------------------------------------------------------
-- SKILLS: END
-- ------------------------------------------------------------
}
###############
# Damage Calc #
###############
# lifted from https://underhound.eu/crawl/rcfiles/crawl-git/HyperOdds.rc
{
local previous_hp = 0
local previous_mp = 0
local previous_form = ""
local was_berserk_last_turn = false
function AnnounceDamage()
local current_hp, max_hp = you.hp()
local current_mp, max_mp = you.mp()
--Things that increase hp/mp temporarily really mess with this
local current_form = you.transform()
local you_are_berserk = you.berserk()
local max_hp_increased = false
local max_hp_decreased = false
if (current_form ~= previous_form) then
if (previous_form:find("dragon") or
previous_form:find("statue") or
previous_form:find("tree") or
previous_form:find("ice")) or
previous_form:find("hydra")then
max_hp_decreased = true
elseif (current_form:find("dragon") or
current_form:find("statue") or
current_form:find("tree") or
previous_form:find("ice")) or
previous_form:find("hydra")then
max_hp_increased = true
end
end
if (was_berserk_last_turn and not you_are_berserk) then
max_hp_decreased = true
elseif (you_are_berserk and not was_berserk_last_turn) then
max_hp_increased = true
end
--crawl.mpr(string.format("previous_form is: %s", previous_form))
--crawl.mpr(string.format("current_form is: %s", current_form))
--crawl.mpr(string.format("max_hp_increased is: %s", max_hp_increased and "True" or "False"))
--crawl.mpr(string.format("max_hp_decreased is: %s", max_hp_decreased and "True" or "False"))
--crawl.mpr(string:format("you_are_berserk is: %s", you_are_berserk and "True" or "False"))
--crawl.mpr(string:format("was_berserk_last_turn is: %s", was_berserk_last_turn and "True" or "False"))
--Skips message on initializing game
if previous_hp > 0 then
local hp_difference = previous_hp - current_hp
local mp_difference = previous_mp - current_mp
if max_hp_increased or max_hp_decreased then
if max_hp_increased then
crawl.mpr("You now have " .. current_hp .. "/" .. max_hp .. " hp.")
else
crawl.mpr("You now have " .. current_hp .. "/" .. max_hp .. " hp.")
end
else
local hp_percent = current_hp / max_hp
local color = ""
--On losing health
if (current_hp < previous_hp) then
if current_hp <= (max_hp * 0.30) then
color = "lightred"
elseif current_hp <= (max_hp * 0.50) then
color = ""
elseif current_hp <= (max_hp * 0.70) then
color = "yellow"
elseif current_hp <= (max_hp * 0.90) then
color = "lightgrey"
else
color = "green"
end
crawl.mpr(string.format("You take %i damage, %sand have %i/%i hp (%.0f%%).%s",
hp_difference,
color ~= "" and "<" .. color .. ">" or "",
current_hp, max_hp, hp_percent * 100,
color ~= "" and "" .. color .. ">" or ""))
if hp_difference > (max_hp * 0.20) then
crawl.mpr("MASSIVE DAMAGE!!")
end
end
--On gaining more than 1 health
if (current_hp > previous_hp) then
--Removes the negative sign
local health_inturn = (0 - hp_difference)
if (health_inturn > 1) and not (current_hp == max_hp) then
if current_hp <= (max_hp * 0.30) then
color = "lightred"
elseif current_hp <= (max_hp * 0.50) then
color = "red"
elseif current_hp <= (max_hp * 0.70) then
color = "yellow"
elseif current_hp <= (max_hp * 0.90) then
color = "lightgrey"
else
color = "green"
end
crawl.mpr(string.format("You regained %i hp, %sand now have %i/%i hp (%.0f%%).%s",
health_inturn,
color ~= "" and "<" .. color .. ">" or "",
current_hp, max_hp, hp_percent * 100,
color ~= "" and "" .. color .. ">" or ""))
end
if (current_hp == max_hp) then
crawl.mpr("Health restored: " .. current_hp .. "")
end
end
--On gaining more than 1 magic
if (current_mp > previous_mp) then
--Removes the negative sign
local mp_inturn = (0 - mp_difference)
if (mp_inturn > 1) and not (current_mp == max_mp) then
if current_mp < (max_mp * 0.25) then
crawl.mpr("You regained " .. mp_inturn .. " mp, and now have " .. current_mp .. "/" .. max_mp .. " mp.")
elseif current_mp < (max_mp * 0.50) then
crawl.mpr("You regained " .. mp_inturn .. " mp, and now have " .. current_mp .. "/" .. max_mp .. " mp.")
else
crawl.mpr("You regained " .. mp_inturn .. " mp, and now have " .. current_mp .. "/" .. max_mp .. " mp.")
end
end
if (current_mp == max_mp) then
crawl.mpr("MP restored: " .. current_mp .. "")
end
end
--On losing magic
if current_mp < previous_mp then
if current_mp <= (max_mp / 5) then
crawl.mpr("You now have " .. current_mp .. "/" ..max_mp .." mp.")
elseif current_mp <= (max_mp / 2) then
crawl.mpr("You now have " .. current_mp .. "/" ..max_mp .." mp.")
else
crawl.mpr("You now have " .. current_mp .. "/" ..max_mp .." mp.")
end
end
end
end
--Set previous hp/mp and form at end of turn
previous_hp = current_hp
previous_mp = current_mp
previous_form = current_form
was_berserk_last_turn = you_are_berserk
end
}
{
function items_in_class(class, skip)
local its = {}
for _, it in pairs(items.inventory()) do
-- don't include items in slots a (0) and b (1) for weapon swapping
if it.slot > 1 or skip == false then
if it.class() == class then
table.insert(its, it)
end
end
end
return its
end
function add_or_replace(str, prefix, value)
escaped = string.gsub(prefix, '%+.*', '%%+')
value = tostring(value)
local s, n = string.gsub(str, escaped .. '%S*', prefix .. value)
if n == 0 then
if #s > 0 then
s = s .. ' '
end
s = s .. prefix .. value
end
return s
end
function is_two_handed(it)
return string.find(tostring(it.description), 'a two-%S+ weapon')
end
function is_a_shield(it)
return string.find('buckler, kite shield, tower shield', it.subtype(false))
end
function uninscribe_item(it)
local ins = ''
for token in string.gmatch(it.inscription, '%S+') do
if string.match(token, '^[@!=+]') then
if #ins > 0 then
ins = ins .. ' '
end
ins = ins .. token
end
end
return it.inscribe(ins, false)
end
function uninscribe_items()
return tidy_inventory(true, true)
end
-- x = 'n'; it = items.inslot(items.letter_to_index(x)); crawl.mpr(string.format('> %s | %s | %s', it.name('qual'), it.subtype(false), it.ego(true)))
function auto_inscribe_item(it)
if not it.inscribe then
return
end
local subtype = it.subtype(false)
local ins = it.inscription
local dr = it.damage_rating and it.damage_rating() or nil
if dr ~= nil then
ins = add_or_replace(ins, 'd:', dr)
end
local cur_atk_delay = item_cur_atk_delay(it)
if cur_atk_delay ~= nil then
ins = add_or_replace(ins, 's:', cur_atk_delay)
end
if dr ~= nil and cur_atk_delay ~= nil then
ins = add_or_replace(ins, 'dpt:', string.format('%.1f', dr / cur_atk_delay))
end
if is_two_handed(it) then
ins = add_or_replace(ins, 'h:', 2)
end
if it.reach_range ~= nil and it.reach_range > 1 then
ins = add_or_replace(ins, 'r:', it.reach_range)
end
if (it.ac ~= nil and it.ac ~= 0)
or (it.encumbrance ~= nil and it.encumbrance ~= 0) then
if it.ac ~= nil then
ins = add_or_replace(ins, is_a_shield(it) and 'sh:' or 'ac:', it.ac)
end
if it.encumbrance ~= nil then
ins = add_or_replace(ins, 'er:', it.encumbrance)
end
end
local ego = it.ego(true)
if ego ~= nil then
local fullname = it.name('plain')
local name = it.name('qual', true)
for token in string.gmatch(ego, '%S+') do
local escaped = string.gsub(token, '%+', '%%+')
if not string.find(string.lower(name), string.lower(escaped))
and not string.find(string.lower(fullname), string.lower(escaped)) then
ins = add_or_replace(ins, token, '')
end
end
end
local mapping = {
['acid dragon scales']='rCorr',
['fire dragon scales']='rF++ rC-',
['golden dragon scales']='rF+ rC+ rPois',
['ice dragon scales']='rC++ rF-',
['pearl dragon scales']='rN+',
['quicksilver dragon scales']='Will+',
['shadow dragon scales']='Stlth+',
['steam dragon scales']='rSteam',
['storm dragon scales']='rElec',
['swamp dragon scales']='rPois',
['troll leather armour']='Regen+' }
if mapping[subtype] ~= nil then
for token in string.gmatch(mapping[subtype], '%S+') do
token, value = string.match(token, '([^%+%-]+.-)([%+%-]*)')
ins = add_or_replace(ins, token, value)
end
end
return it.inscribe(ins, false)
end
function tidy_inventory(quiet, uninscribe)
if is_stoat_soup then
crawl.mpr('Inventory tidying not supported.', 25)
return
end
local gear_classes = { 'Hand Weapons', 'Missiles', 'Armour', 'Magical Staves', 'Jewellery', 'Talismans' }
local consumable_classes = { 'Potions', 'Scrolls', 'Wands', 'Miscellaneous' }
local classes
if not is_bcrawl then
classes = gear_classes
else
classes = { 'Hand Weapons', 'Missiles', 'Armour', 'Magical Staves', 'Jewellery', 'Talismans', 'Wands', 'Scrolls', 'Potions' }
end
-- skip a (0) and b (1) for weapon swap slots
local offset = 2
for _, c in ipairs(classes) do
local its = items_in_class(c, false)
for _, it in ipairs(its) do
if uninscribe then
uninscribe_item(it)
else
auto_inscribe_item(it)
end
end
local n = #items_in_class(c)
if not quiet then
crawl.mpr(string.format('(%s) ========== begin class: %s (%s) ==========', offset, c, n), 25)
end
for i = 1, n do
local its = items_in_class(c)
table.sort(its, function(a, b)
-- local a_value = a.name('qual')
-- local b_value = b.name('qual')
-- if a_value ~= b_value then
-- return a_value < b_value
-- end
-- In older crawl, unidentified items will not disclose their
-- details to Lua, returning nils.
if a == nil or b == nil then
return a ~= nil and b == nil
end
local a_subtype = a.subtype(false)
local b_subtype = b.subtype(false)
-- In older crawl, unidentified items will not disclose their
-- details to Lua, returning nils.
if a_subtype == nil or b_subtype == nil then
return a_subtype ~= nil and b_subtype == nil
end
if a_subtype ~= b_subtype then
return a_subtype < b_subtype
end
if a.plus ~= b.plus then
return (a.plus or 0) > (b.plus or 0)
end
if a.name() == b.name() then
return a.slot < b.slot
end
return a.name() < b.name()
end)
if not quiet then
crawl.mpr(string.format('# (sorted)'), 25)
end
local found = false
for j = i, #its do
local it = its[j]
local idx = offset + j - 1
if not quiet then
crawl.mpr(string.format('# offset=%s, i=%s, j=%s, idx=%s, slot=%s, it=%s', offset, i, j, idx, it.slot, tostring_item(it)), 25)
end
if it.slot ~= nil and it.slot ~= idx then
local to = items.inslot(idx)
if not quiet then
crawl.mpr(string.format('# %s (%s) => %s (%s)',
tostring_item(it), it.slot,
tostring_item(to), idx), 25)
crawl.mpr(string.format('# items.swap_gear_slots(%s, %s, true)',
it.slot, idx), 25)
end
if items.swap_gear_slots then
items.swap_gear_slots(it.slot, idx, true)
else
items.swap_slots(it.slot, idx, true)
end
found = true
break
end
end
if not found then
break
end
end
offset = offset + n
if not quiet then
crawl.mpr(string.format('(%s) ========== end class: %s (%s) ==========', offset, c, n), 25)
end
end
crawl.mpr('Inventory tidied.', 25)
end
function tidy_inventory_quiet()
return tidy_inventory(true)
end
}
macros += M - ===tidy_inventory_quiet
macros += M ] ===tidy_inventory
{
function analyze_spells()
local s = you.spells()
local out = {}
for _, name in ipairs(s) do
local desc = spells.describe(name)
local dmg = string.match(desc, 'Damage: ([^*%s]+)')
if dmg then
local mult, dice = string.match(dmg, '(%d+)x(%S+)')
if mult then
dmg = ''
for i = 1, mult do
if #dmg > 0 then
dmg = dmg .. ' + '
end
dmg = dmg .. dice
end
end
-- 6-21 -> d{6..21}
dmg = string.gsub(dmg, '^(%d+)-(%d+).*', 'd{%1..%2}')
-- 2d(25-37) -> 2d{25..37}
dmg = string.gsub(dmg, '^(%d+d)%((%d+)-(%d+)%).*', '%1{%2..%3}')
local str = string.format('output %s named "%s %s%%"', dmg, name, spells.power_perc(name))
table.insert(out, str)
end
end
crawl.mpr('\n' .. table.concat(out, '\n'))
end
}
# [^&] doesn't work here, but \{-9} (webtiles) or \{-41} (tiles) does:
: if not is_stoat_soup and not is_bcrawl then
bindkey = [\{-9}] CMD_LUA_CONSOLE
bindkey = [\{-41}] CMD_LUA_CONSOLE
: else
bindkey = [&] CMD_LUA_CONSOLE
:end
travel_delay = 10
# travel_open_doors = approach
{
crawl.setopt("travel_open_doors = false")
toggleable_settings = {
autopickup_weapons=true,
autofight_stop=50,
explore_auto_rest=false,
rest_wait_both=false,
rest_wait_percent=100,
spell_menu=false,
travel_open_doors=false,
explore_never_die=true,
warn_hatches=false }
function set_travel_open_doors(value)
local options = { avoid=true, approach=true, open=true, ['true']=true, ['false']=true }
if options[tostring(value)] ~= nil then
crawl.setopt(string.format('travel_open_doors = %s', tostring(value)))
end
end
function set_or_toggle_setting(option, value_on, value_off)
local msgch_diagnostic = crawl.msgch_num('diagnostic')
local value = toggleable_settings[option]
if value_on ~= nil and value_off ~= nil then
toggleable_settings[option] = not toggleable_settings[option]
if toggleable_settings[option] then
value = value_on
else
value = value_off
end
elseif value_on ~= nil and value_off == nil then
value = value_on
else
toggleable_settings[option] = not toggleable_settings[option]
value = toggleable_settings[option]
end
local opt = string.format('%s = %s', option, tostring(value))
crawl.mpr(string.format('Setting %s', opt), msgch_diagnostic)
crawl.setopt(opt)
end
function toggle_settings()
local msgch_prompt = crawl.msgch_num('prompt')
crawl.mpr(string.format(
'Toggle (a)utofight_stop [%s], (A)utopickup_weapons [%s], (t)ravel_open_doors [%s], (e)xplore_auto_rest [%s], (r)est_wait_both [%s], rest_wait_(p)ercent [%s], (s)pell_menu [%s], (f)iltered find, never (d)ie in explore mode [%s], (c)lear force_more_message and monster_alert, tidy (i/I)nventory, (u)ninscribe inventory, (w)arn_hatches [%s]?',
tostring(toggleable_settings['autofight_stop']),
tostring(toggleable_settings['autopickup_weapons']),
tostring(toggleable_settings['travel_open_doors']),
tostring(toggleable_settings['explore_auto_rest']),
tostring(toggleable_settings['rest_wait_both']),
tostring(toggleable_settings['rest_wait_percent']),
tostring(toggleable_settings['spell_menu']),
tostring(toggleable_settings['explore_never_die']),
tostring(toggleable_settings['warn_hatches'])), msgch_prompt)
local num = crawl.getch()
local ch = string.char(num)
if ch == '\x1b' then
crawl.mpr('Okay, then.', msgch_prompt)
elseif ch == 'a' then
crawl.mpr('New threshold? ', msgch_prompt)
local value = crawl.c_input_line()
set_or_toggle_setting('autofight_stop', value)
elseif ch == 'A' then
set_or_toggle_setting('autopickup_weapons')
elseif ch == 'c' then
crawl.mpr('Clearing force_more_message')
crawl.setopt("force_more_message = nil")
crawl.mpr('Clearing monster_alert')
crawl.setopt("monster_alert = nil")
elseif ch == 'd' then
set_or_toggle_setting('explore_never_die')
elseif ch == 'e' then
set_or_toggle_setting('explore_auto_rest')
elseif ch == 'f' then
crawl.sendkeys(control('f') .. '@ && !!gate && !!door && !!transp && !!gold\r')
elseif ch == 'i' then
tidy_inventory_quiet()
elseif ch == 'I' then
tidy_inventory()
elseif ch == 'p' then
crawl.mpr('New percentage? ', msgch_prompt)
local value = crawl.c_input_line()
set_or_toggle_setting('rest_wait_percent', value)
elseif ch == 'r' then
set_or_toggle_setting('rest_wait_both')
elseif ch == 's' then
set_or_toggle_setting('spell_menu')
elseif ch == 't' then
set_or_toggle_setting('travel_open_doors')
elseif ch == 'u' then
tidy_inventory(true, true)
elseif ch == 'w' then
set_or_toggle_setting('warn_hatches')
else
crawl.mpr('Huh?')
end
end
function autopickup_weapons_func(it, _name)
if it.class(true) == 'weapon' and not toggleable_settings['autopickup_weapons'] then
return false
end
end
-- clear_autopickup_funcs()
add_autopickup_func(autopickup_weapons_func)
}
macros += M _ ===toggle_settings
{
if not crawl.is_webtiles() then
crawl.setopt('msg_min_height = 25')
crawl.setopt('msg_max_height = 25')
end
}
tile_window_height = -200
msg_webtiles_height = 15
## slot += label:key
## item_slot ^= regexp:key
# Space = CMD_EXPLORE
# macros += M \{32} o
# NP0 = CMD_EXPLORE
macros += M \{-1000} o
# NP+ = >
macros += M \{-1016} >
# NP- = <
macros += M \{-1018} <
# PgDn = G>
macros += M \{-245} G>
# PgUp = G<
macros += M \{-246} G<
# Num Lock (Clear) = G> (webtiles only)
macros += M \{-247} G>
# crawl.mpr() will print to the console.
{
-- Press "tab" when enemies are visible and "o" when they are not
function autoplay(autofire)
autofire = autofire or false
if you.feel_safe() then
crawl.sendkeys("o")
else
-- {9} = Tab, {-233} = Shift-Tab (or p)
if autofire then
crawl.sendkeys({-233})
else
if is_bcrawl then
crawl.sendkeys(string.char(9))
else
crawl.sendkeys({9})
end
end
end
end
function autoplay_autofight()
autoplay()
end
function autoplay_autofire()
autoplay(true)
end
}
# NP/ = autoplay_autofight
macros += M \{-1012} ===autoplay_autofight
{
if is_stoat_soup or is_bcadrencrawl then
crawl.setopt("macros += M / ===autoplay_autofight")
end
}
# NP* = autoplay_autofire
# macros += M \{-1015} ===autoplay_autofire
macros += M \{-1015} p
{
if is_bcrawl or is_bcadrencrawl then
crawl.setopt("macros += M * zaf")
end
}
# Ctrl-1 \{-15} = CMD_AUTOFIGHT_NOMOVE
bindkey = [^1] CMD_AUTOFIGHT_NOMOVE
{
function smart_rest()
local hp, max_hp = you.hp()
local mp, max_mp = you.mp()
if hp < max_hp or mp < max_mp then
crawl.do_commands({"CMD_REST"})
else
crawl.mpr("HP and MP is already full. Ctrl-5 to rest for 100 turns.")
end
end
}
macros += M 5 ===smart_rest
# \{-1005} = NP5
macros += M \{-1005} ===smart_rest
# webtiles: [^5] = Ctrl-5
bindkey = [^5] CMD_REST
# tiles: \{-43} = Ctrl-5
: if not is_stoat_soup and not is_bcrawl then
bindkey = [\{-43}] CMD_REST
: end
# See: crawl-ref/source/initfile.cc item_class_by_sym()
autopickup = $?!+"/|(0%
# " closing quote because of syntax coloring
# drop_disables_autopickup = true
ae := autopickup_exceptions
ae ^= boomerang, >javelin, >stone, >talisman
: end
# : if you.race() == 'Minotaur' and you.class() == 'Fighter' then
# ae += book
# : end
: if you.race() == 'Felid' then
fail_severity_to_confirm = 0
fail_severity_to_quiver = 5
: end
######################################################################
# Add the following to your options file to automatically pick up
# armour for non-body armour slots (gloves, boots, etc.), if you don't
# already have an item equipped there.
{
-- x = 'j'; it = items.inslot(items.letter_to_index(x)); crawl.mpr(string.format('>> %s / %s', it.class(true), it.subtype()))
function smart_autopickup_func(it, _name)
if it.is_useless then
return false
end
local name = it.name('qual')
if name == 'orb' then
return
end
if name == 'gold piece' then
return true
end
if it.class(true) == 'armour' then
local good_slots = {cloak="cloak", helmet="helmet", gloves="gloves",
boots="boots", barding="barding", offhand="offhand"}
local slot_type = it.subtype(true)
local subtype = it.subtype(false)
-- if good_slots[slot_type] ~= nil and items.slot_is_available(slot_type) == true then
if items.slot_is_available(slot_type) then
return true
end
if false then
local cur = items.equipped_at(slot_type == 'body' and 'armour' or slot_type)
if cur == nil then
crawl.mpr(string.format('> %s (something is wrong, cur is nil, we should have returned true earlier)', name))
return
end
-- crawl.mpr(string.format('> %s (branded:%s, ac:%s, plus:%s)', name, it.branded, it.ac, it.plus))
if it.branded and it.plus == nil then
crawl.mpr(string.format('> %s (branded and plus unknown, we need to go identify it)', name))
return true
end
-- crawl.mpr(string.format('> %s (cur:%s, branded:%s, ac:%s, plus:%s)', name, cur.name('qual'), cur.branded, cur.ac, cur.plus))
local found = false
for _, it2 in pairs(items.inventory()) do
local n = it2.name('qual')
if n ~= 'orb' then
if it2.class(true) == slot_type then
if it2.ac + it2.plus > it.ac + it.plus then
return true
end
end
end
end
end
end
end
-- clear_autopickup_funcs()
if items.slot_is_available and not is_stoat_soup then
add_autopickup_func(smart_autopickup_func)
end
}
explore_greedy = true
explore_greedy_visit += glowing_items, artefacts
explore_greedy_visit -= stacks
explore_item_greed = 999
explore_stop = stairs,shops,altars,portals,branches,runed_doors
explore_stop += greedy_pickup_smart, glowing_items, artefacts
# Sets autoexplore to favor traveling towards walls, the higher the more
# favored. Negative values instead travels away from walls. Default 0.
explore_wall_bias = 1
explore_auto_rest = false
rest_wait_ancestor = false
rest_wait_both = false
rest_wait_percent = 90
#################### VIEW AND CONTROLS #####################
tile_map_scale = 1.0
tile_viewport_scale = 1.25
#tile_web_mouse_control = false
############################################################
# default = 50
autofight_stop = 50
# attempt to escape webs or nets
autofight_caught = true
# use thrown items during autofight?
autofight_fires = false
autofight_nomove_fires = false
# default = 10
hp_warning = 50
# default = 70:yellow, 40:red
# hp_colour = 80:yellow, 60:lightred, 40:red
hp_colour = 100:green, 85:lightgreen, 67:lightblue, 50:yellow, 33:lightmagenta, 15:red
mp_colour = 100:green, 85:lightgreen, 67:lightblue, 50:yellow, 33:lightmagenta, 15:red
# when using lua console:
# crawl.setopt("hp_warning = 0")
warn_hatches = false
warn_contam_cost = true
# fail_severity_to_confirm = 3
# fail_severity_to_quiver = 2
############# FORCE MORE AND AUTOEXPLORE STOP ##############
more := force_more_message
stop := runrest_stop_message
more += Found a faded altar of an unknown god
stop += Found a faded altar of an unknown god
more += Found a staircase to the Ecumenical Temple
stop += Found a staircase to the Ecumenical Temple
more += Found an escape hatch in the ceiling
stop += Found an escape hatch in the ceiling
more += seems less pained.
stop += seems less pained.
more += Your body becomes as fragile as glass
more += Your eldritch tentacle suddenly becomes enraged
stop += Your eldritch tentacle suddenly becomes enraged
# The portal closes; your eldritch tentacle is severed.
# The portal closes; something is severed.
more += The portal closes; .* is severed
# The Killer Klown pies you viciously!
# The klown pie hits you! Blueberry! An unnatural silence engulfs you.
more += An unnatural silence engulfs you
more += Your transformation is almost over
stop += Your transformation is almost over
more += The roar of the dragon horde subsides
stop += The roar of the dragon horde subsides
# more += You.*engulfed.*chaos.*
more += breathes chaos
more += You detect
# runrest_ignore_message ^= Your toxic aura wanes.
more += You are slowing down.
more += You fail to use your ability
more += You miscast
more += You are too exhausted
more += The catoblepas breathes a plume of calcifying dust at you
more += You suddenly lose the ability to move
stop += You suddenly lose the ability to move
more += You are poisoned
stop += You are poisoned
more += The acid corrodes you[.!]
more += You are covered in (intense )?liquid fire
flash_screen_message += The liquid fire burns you
flash_screen_message += You are on fire
# more += The shock serpent discharges a tendril of electricity
# more += The shock serpent's electric aura discharges\, shocking you[.!]
more += The .* electric aura discharges\, shocking you[.!]
more += The bolt of electricity hits you[.!]
# The black draconian breathes lightning at you.
more += The bolt of lightning hits you[.!]
# The drowned soul touches you. The drowned soul drowns you!
more += The .* drowns you
message_colour += lightcyan:The .* drowns you
flash_screen_message += The .* drowns you
# The water elemental engulfs you!
more += The .* engulfs you[.!]
message_colour += lightcyan:The .* engulfs you[.!]
flash_screen_message += The .* engulfs you[.!]
# Water floods into your lungs!
more += Water floods into your lungs
message_colour += lightcyan:Water floods into your lungs
flash_screen_message += Water floods into your lungs
# You finish coughing all the water out of your lungs.
more += You finish coughing all the water out of your lungs
# The Tzitzimitl calls on the powers of darkness!
# Your body is wracked with pain!
more += Your body is wracked with pain
message_colour += lightcyan:Your body is wracked with pain
flash_screen_message += Your body is wracked with pain
more += You are confused
more += You are marked
more += You are slowed
more += You are corroded
more += You are mesmerised
more += You feel yourself slow down
more += You are constricted
more += You encounter .* wielding .* distortion
more += is wielding .* distortion
more += hits you with .* distortion
# The naga ritualist invokes the aid of its god against you.
# You feel yourself grow more vulnerable to poison.
more += You feel yourself grow more vulnerable
message_colour += lightcyan:You feel yourself grow more vulnerable
flash_screen_message += You feel yourself grow more vulnerable
more += You feel your attacks grow feeble
more += Your willpower is stripped away
more += You hear a loud "Zot"
more += The power of Zot is invoked against you
# more += Your walking alembic finishes brewing potions and dispenses them
more += Mmmm\.\.\. tastes like
# For just a moment, the protean progenitor begins to look like , then it explodes!
more += For just a moment\, .* begins to look like .*\, then it explodes!
# May want to do this if it's too spammy for Gnoll.
# : if you.race() ~= 'Gnoll' then
# more += Your .* skill increases to level .*!
# : end
more += Training target .* for .* reached
# the spriggan druid
more += With its final breath\, .* offers up its power to the beasts of the wild
more += seems to grow more fierce
# You have finished your manual of %s and %stoss it away.
more += You have finished your manual
stop += You have finished your manual
monster_alert += hydra
monster_alert += moth of wrath
monster_alert += guardian serpent
monster_alert += revenant
monster_alert += distortion
monster_alert += hornet
monster_alert += two-headed ogre
monster_alert += acid dragon
monster_alert += shock serpent
monster_alert += fire giant
monster_alert += frost giant
monster_alert += ettin
monster_alert += deep elf annihilator
monster_alert += lich
# these things can flood/drown you
monster_alert += water elemental
# 50 damage hit, Manifold Assault and Throw Bolas - yikes!
monster_alert += oni incarcerator
# xykzyl has malmutate
monster_alert += zykzyl
# total chad mode, when explore mode is on:
#
# crawl.setopt("hp_warning = 0")
# crawl.setopt("autofight_stop = 0")
# crawl.enable_more(false)
# : function go_chad_mode()
# : crawl.enable_more(false)
# hp_warning = 0
# autofight_stop = 0
# : end
################### MESSAGE AND DISPLAY ####################
# item_stack_summary_minimum = 4
default_manual_training = true
default_show_all_skills = true
auto_hide_spells = false
cloud_status = true
always_show_zot = true
always_show_gems = true
more_gem_info = true
tile_show_threat_levels = tough, nasty, unusual
unusual_monster_items += wand
unusual_monster_items += javelin, throwing net
unusual_monster_items += curare, atropa, datura, dispersal
unusual_monster_items += venom, protection, elec, holy wrath, draining, distortion, chaos
# "unusual_monster_items += vulnerable:venom:5" will hilight monsters with venom weapons while the player is non-immune to them and XL 5 or below.
message_colour += lightblue:You encounter
# Uskayaw piety messages.
message_colour += lightcyan:You can now stomp with the beat
message_colour += lightcyan:You can now pass through a line of other dancers
message_colour += lightcyan:Uskayaw will force your foes to helplessly watch your dance
message_colour += lightcyan:Uskayaw will force your foes to share their pain
message_colour += lightcyan:You can now merge with and destroy a victim
force_more_message += You can now pass through a line of other dancers
force_more_message += You can now merge with and destroy a victim
message_colour += lightcyan:Uskayaw links your audience in an emotional bond
message_colour += lightcyan:Uskayaw prepares the audience for your solo
message_colour += cyan:You can no longer pass through a line of other dancers
message_colour += cyan:You can no longer merge with and destroy a victim
# Ru piety messages.
force_more_message += Ru believes you are ready to make a new sacrifice
####################### SPELL SLOTS ########################
# Always show the full-screen spell selection menu?
# spell_menu = true
force_spell_targeter += Arcjolt
force_spell_targeter += Blink
force_spell_targeter += Conjure Ball Lightning
force_spell_targeter += Death Channel
force_spell_targeter += Death's Door
force_spell_targeter += Detonation Catalyst
force_spell_targeter += Dragon's Call
force_spell_targeter += Eringya's Noxious Bog
force_spell_targeter += Fireball
force_spell_targeter += Fire Storm
force_spell_targeter += Fortress Blast
force_spell_targeter += Freezing Cloud
force_spell_targeter += Hoarfrost Cannonade
force_spell_targeter += Hellfire Mortar
force_spell_targeter += Ignite Poison
force_spell_targeter += Irradiate
force_spell_targeter += Iskenderun's Mystic Blast
force_spell_targeter += Leda's Liquefaction
force_spell_targeter += Malign Gateway
force_spell_targeter += Manifold Assault
force_spell_targeter += Olgreb's Toxic Radiance
force_spell_targeter += Ozocubu's Refrigeration
force_spell_targeter += Permafrost Eruption
force_spell_targeter += Plasma Beam
force_spell_targeter += Polar Vortex
force_spell_targeter += Scorch
force_spell_targeter += Silence
force_spell_targeter += Starburst
force_spell_targeter += Static Discharge
force_spell_targeter += Summon Forest
## Uskayaw
force_ability_targeter += Stomp
## Cheibriados
force_ability_targeter += Bend Time
force_ability_targeter += Temporal Distortion
force_ability_targeter += Slouch
force_ability_targeter += Step From Time
# doesn't work
force_spell_targeter += Animate Dead
force_spell_targeter += Fulsome Fusillade
# doesn't work: https://github.com/crawl/crawl/issues/3811
force_spell_targeter += Ozocubu's Armour
force_scroll_targeter += immolation
force_scroll_targeter += noise
force_scroll_targeter += silence
force_scroll_targeter += vulnerability
force_scroll_targeter += butterflies
: if you.race() ~= 'Djinni' then
ss := spell_slot
: else
ss := dummy
: end
ss += Apportation:q
ss += Arcjolt:JA
ss += Blink:bilk
ss += Bombard:r
ss += Brom's Barrelling Boulder:rB
ss += Dispel Undead:D
ss += Fireball:f
ss += Fire Storm:FS
ss += Fortress Blast:FB
ss += Fugue of the Fallen:f
ss += Gloom:g
ss += Hailstorm:H
ss += Hellfire Mortar:hH
ss += Ignite Poison:IP
ss += Iskenderun's Battlesphere:BS
ss += Kiss of Death:k
ss += Lee's Rapid Deconstruction:L
ss += Lesser Beckoning:tl
ss += Martyr's Knell:m
ss += Mephitic Cloud:cf
ss += Momentum Strike:m
ss += Nazja's Percussive Tempering:ty
ss += Olgreb's Toxic Radiance:rR
ss += Passage of Golubria:g
ss += Passwall:w
ss += Permafrost Eruption:e
ss += Petrify:e
ss += Plasma Beam:e
ss += Shatter:s
ss += Slow:s
ss += Spellspark Servitor:v
ss += Sublimation of Blood:s
ss += Summon Forest:f
ss += Vhi's Electric Charge:v
## Hedge Wizard Start
: if you.class() == 'Hedge Wizard' then
ss += Magic Dart:a
: else
ss += Magic Dart:D
: end
# ss += Blink:b
# ss += Call Imp:c
# ss += Grave Claw:d
# ss += Mephitic Cloud:e
## Forgewright Start
: if you.class() ~= 'Forgewright' then
ss += Forge Blazeheart Golem:G
ss += Forge Lightning Spire:SL
: end
## Conjurer Start
# ... Magic Dart
ss += Searing Ray:bs
ss += Fulminant Prism:cF
ss += Iskenderun's Mystic Blast:dM
## Enchanter Start
ss += Ensorcelled Hibernation:ah
ss += Tukima's Dance:btD
ss += Confusing Touch:ct
ss += Gloom:dgG
## Summoner Start
ss += Summon Small Mammal:am
ss += Call Imp:bciI
ss += Call Canine Familiar:cD
ss += Eringya's Surprising Crocodile:dC
ss += Summon Seismosaurus Egg:E
## Necromancer Start
ss += Soul Splinter:asS
ss += Grave Claw:bcgG
ss += Vampiric Draining:cvV
ss += Animate Dead:dAD
ss += Curse of Agony:eC
## Fire Elementalist Start
ss += Foxfire:ao
ss += Scorch:bs
: if you.class() ~= 'Hexslinger' then
ss += Inner Flame:iI
: end
ss += Volatile Blastmotes:cvV
ss += Flame Wave:dw
## Air Elementalist Start
ss += Shock:as
ss += Static Discharge:bS
ss += Swiftness:cw
ss += Airstrike:dA
## Ice Elementalist Start
ss += Freeze:aF
ss += Frozen Ramparts:br
ss += Ozocubu's Armor:co
ss += Summon Ice Beast:dS
####################### AUTOINSCRIBE #######################
ai := autoinscribe
# autoinscribe =f on ranged weapons to keep them from
# auto-quivering when wielding them
ai += potion:!q
ai += (bad|dangerous)_item.*scroll:!r
ai += scrolls? of (fog|teleportation|poison|revelation|summoning):!r
ai += ranged weapon:=f
ai += boomerang:@f1
ai += javelin:@f2
ai += large rock:@f3
###################### DUMP AND NOTES ######################
dump_message_count = 250
dump_item_origins = all
dump_order += turns_by_place, kills_by_place
note_all_skill_levels = true
note_items += wand, potions?, scrolls?
note_hp_percent = 50
note_messages += (You add the spell|wells up from within)
note_messages += You quaff a potion
note_messages += As you read (a|the) scroll
note_messages += You invoke
# haste
note_messages += You feel yourself speed up
# curing, healing
# This seems to also appear when Makleb gives you HP for killing things.
# note_messages += You feel better
note_messages += You feel much better
# resistance
note_messages += You feel protected
# brilliance
note_messages += You feel clever all of a sudden
# lignification
note_messages += You turn into a tree
# ambrosia
note_messages += You savour every drop. You feel invigorated
# invisibility
note_messages += You fade into invisibility
# magic
note_messages += You savour every drop. Magic courses through your body
# might
note_messages += You feel very mighty all of a sudden
# cancellation
note_messages += You feel magically purged
# enlightenment
note_messages += You feel very buoyant
# attraction
note_messages += You feel attractive to monsters
# heavenly storm
note_messages += The air is filled with shimmering golden clouds
note_messages += The storm will not cease as long as you keep fighting
note_messages += The heavenly storm settles
##### Sound Support (requires DWEM module) #########################
# sound_on = true
# one_SDL_sound_channel = true
# sound_fade_time = 0.5
# sound_volume = 0.4
# bgm_volume = 0.4
# sound_pack += https://crawl-br.roguelikes.gg/soundpacks/osp-latest.zip:["init.txt"]
# sound_pack += https://crawl-br.roguelikes.gg/soundpacks/BindTheEarth.zip:["init.txt"]
############################################################
{
function c_answer_prompt(prompt)
if toggleable_settings['explore_never_die'] and prompt == "Die?" then
crawl.mpr("(You would have died, but you're in explore mode.)")
return false
end
end
}
############################################################
# these aren't really necessary:
#
# crawl.setopt("clear_messages = false")
# crawl.setopt("show_more = false")
# crawl.setopt("force_more_message = nil")
{
function ready()
AnnounceDamage()
end
}
{
if is_bcrawl then
crawl.setopt("tile_full_screen = false")
crawl.setopt("auto_butcher = true")
-- crawl.setopt("auto_butcher_max_chunks = 2")
crawl.setopt("macros += M - <")
crawl.setopt("macros += M + >")
crawl.setopt("macros += M \\{32} ===false")
crawl.setopt("tile_player_tile = tile:MONS_MARA")
end
}
{
if is_bcadrencrawl then
crawl.setopt("show_more = false")
crawl.setopt("macros += M - <")
crawl.setopt("macros += M + >")
end
}
# tile_player_tile = tile:MONS_MARA
# autopickup_exceptions ^= >shield