# TEAMCAPTAIN zkyp rest_wait_both = true sort_menus = true : equipped, identified, basename, qualname, curse, qty autofight_stop = 50 automagic_enable = true automagic_slot = x show_inventory_weights = true default_manual_training = true view_delay = 300 show_more = false confirm_butcher = never easy_eat_chunks = true auto_eat_chunks = true auto_drop_chunks = true auto_sacrifice = before_explore tile_map_pixels = 3 autopickup = $?!+"/%|\} autopickup_exceptions += inscription -- better weapons of the same school than anything in your inventory -- * can be disabled with _noup inscription -- * going from one handed to two handed can be enabled with _2h inscription -- items that have better plusses and the same brand as the current item (Ash) -- * brand can be ignored with _plain inscription -- Inscriptions: -- _keep don't replace this item -- _noup don't upgrade this item -- _lock shortcut for both _keep and _noup -- _plain don't consider this item to have an ego or be an artefact -- _2h allow replacing this weapon with a two handed version -- _er consider body armours with er <= to replace this -- TODO: -- handle hides better -- allow not picking up certain artifacts -- some way to allow picking up multiple armour types (robe, leather) -- pickup special good armours (dragon hide/armour, crystal plate) -- add inscriptions to picked up items in certain cases (_2h, _er) -- add options local initialized = false local need_inventory_check = false local found = {} local stackable_classes = { "missile", "potion", "scroll", "food" } local aux_subtypes = { "cloak", "boots", "helmet", "gloves" } local body_armour_data = { { "robe", 2, 0, false }, { "leather armour", 3, 4, false }, { "ring mail", 5, 7, false }, { "scale mail", 6, 11, false }, { "chain mail", 8, 15, false }, { "plate armour", 10, 18, false }, { "crystal plate armour", 14, 24, false }, { "animal skin", 2, 0, false }, { "troll leather armour", 4, 4, true }, { "steam dragon armour", 5, 0, true }, { "mottled dragon armour", 6, 5, true }, { "swamp dragon armour", 7, 7, true }, { "fire dragon armour", 8, 11, true }, { "ice dragon armour", 9, 11, true }, { "pearl dragon armour", 10, 11, true }, { "storm dragon armour", 10, 17, true }, { "gold dragon armour", 12, 25, true }, { "troll hide", 4, 4, true }, { "steam dragon hide", 5, 0, true }, { "mottled dragon hide", 6, 5, true }, { "swamp dragon hide", 7, 7, true }, { "fire dragon hide", 8, 11, true }, { "ice dragon hide", 9, 11, true }, { "pearl dragon hide", 10, 11, true }, { "storm dragon hide", 10, 17, true }, { "gold dragon hide", 12, 25, true } } -- scythe handled the same as halberd local twohanded_weapon_list = { "great sword", "claymore", "battleaxe", "executioner's axe", "dire flail", "great mace", "giant club", "giant spiked club", "halberd", "glaive", "bardiche", "quaterstaff", "lajatang" } local spriggan_onehanded_weapon_list = { "dagger", "short sword", "cutlass", "quickblade", "club", "whip", "mace", "flail", "demon whip", "falchion", "hand axe" } local weapon_upgrade_table = { { "dagger", "short sword", "cutlass", "quickblade" }, { "falchion", "long sword", "blessed falchion", "scimitar", "blessed long sword", "blessed scimitar", "demon blade", "bastard sword", "eudemon blade", "great sword", "blessed bastard sword", "blessed great sword", "claymore", "blessed claymore" }, { "hand axe", "war axe", "broad axe", "battleaxe", "executioner's axe" }, { "club", "whip", "hammer", "mace", "flail", "morningstar", "demon whip", "dire flail", "sacred scourge", "eveningstar", "great mace", "giant club", "giant spiked club" }, { "spear", "trident", "halberd", "demon trident", "trishula", "glaive", "bardiche" }, { "quarterstaff", "lajatang" }, { "hunting sling", "greatsling" }, { "shortbow", "longbow" }, { "hand crossbow", "arbalest", "triple crossbow" } } -- HELPER FUNCTIONS local function Set(list) local set = {} for _, l in ipairs(list) do set[l] = true end return set end local function control(c) return string.char(string.byte(c) - string.byte('a') + 1) end local function stash_search(search) crawl.process_keys(control('f') .. search .. "\r" .. string.char(27) .. string.char(27)) crawl.flush_input() return not crawl.messages(2):find("Can't find anything matching that.") end local function upgrade_list_for_weapon(name) if name == "scythe" then name = "halberd" end local found for row = 1, #weapon_upgrade_table do for col = 1, #weapon_upgrade_table[row] do if name == weapon_upgrade_table[row][col] then found = { row=row, col=col } break end end if found then break end end local result = {} if found then for col = 1, found.col - 1 do result[weapon_upgrade_table[found.row][col]] = true if weapon_upgrade_table[found.row][col] == "halberd" then result["scythe"] = true end end end return result end local function plus_or_0(item) if item.plus == nil then return 0 else return item.plus end end local function er(item) local name = item.name("base") local subtype = item.subtype() if subtype == "shield" then if name == "buckler" then return 1 elseif name == "shield" then return 3 elseif name == "large shield" then return 5 end elseif subtype == "body" then if body_armour_data[name] ~= nil then return body_armour_data[name].er else return 99 end else if name:find("barding") then return 6 else return 0 end end end -- also does SH local function base_ac(item) local name = item.name("base") local subtype = item.subtype() if subtype == "shield" then if name == "buckler" then return 5 elseif name == "shield" then return 8 elseif name == "large shield" then return 13 end elseif subtype == "body" then if body_armour_data[name] ~= nil then return body_armour_data[name].ac else return 2 end else if name:find("barding") then return 4 elseif name == "hat" then return 0 else return 1 end end end -- also does SH local function estimate_ac(item) return base_ac(item) + plus_or_0(item) end local function stackable(class) return stackable_classes[class] ~= nil end local function inventory_match(name_type, name, class) for item in iter.invent_iterator:new(items.inventory()) do if (class == nil or item.class(true) == class) and item.name(name_type) == name then return item end end return nil end local function inscription_er(item) local match = item.name("qual"):match("_er%d+") if match ~= nil then return tonumber(match:sub(4, -1)) end return nil end local function maxer(item) local i = inscription_er(item) if i ~= nil then return i else return er(item) end end local function inscription_keep(item) return item.name("qual"):find("_keep") ~= nil or item.name("qual"):find("_lock") ~= nil end local function inscription_no_upgrade(item) return item.name("qual"):find("_noup") ~= nil or item.name("qual"):find("_lock") ~= nil end local function inscription_plain(item) return item.name("qual"):find("_plain") ~= nil end local function inscription_twohanded(item) return item.name("qual"):find("_2h") ~= nil end local function keep(item) if item == nil then return false end return inscription_keep(item) end local function upgrade(item) if item == nil then return false end return not inscription_no_upgrade(item) end local function special(item) return (item.artefact or item.branded) and not inscription_plain(item) end local function twohanded(item) if item.class(true) ~= "weapon" then return nil end if you.genus() == "formicid" or inscription_twohanded(item) then return true end if you.genus() == "spriggan" then return not (spriggan_onehanded_weapon_list[item.name("base")] ~= nil) end return twohanded_weapon_list[item.name("base")] ~= nil end local function ego(item) if inscription_plain(item) then return "plain" elseif item.artefact then return "artefact" elseif item.ego_type_terse ~= nil then return item.ego_type_terse elseif body_armour_data[item.name("base")] ~= nil and body_armour_data[item.name("base")].ego == true then return "innate" else return "plain" end end local function parse_body_armour_data() local parsed = {} for _, v in ipairs(body_armour_data) do parsed[v[1]] = { ac=v[2], er=v[3], ego=v[4] } end return parsed end local function initialize() for key, value in pairs(found) do if inventory_match("base", key) or stash_search(key .. " && dropped") then found[key] = true end end end local function check_inventory() for key, value in pairs(found) do if value == false and inventory_match("base", key) then found[key] = true end end end -- CALLED BY THE GAME local function autopickup(item) local class = item.class(true) if item.artefact then return true end if found[item.name("base")] ~= nil then return not found[item.name("base")] end if stackable(class) then if inventory_match("qual", item.name("qual"), class) then return true end end if item.name("base"):find("needle") then return found["blowgun"] == false or inventory_match("base", "blowgun") end if class == "armour" then local subtype = item.subtype() local current = nil if subtype == "body" then current = items.equipped_at("armour") else current = items.equipped_at(subtype) end if aux_subtypes[subtype] then if keep(current) then return false end if estimate_ac(item) >= 0 or item.branded then if current == nil then return true end if item.branded and ego(item) ~= ego(current) then return true end if ego(item) == ego(current) and estimate_ac(item) > estimate_ac(current) then return true end end elseif subtype == "body" then if current ~= nil then if er(item) == er(current) and base_ac(item) == base_ac(current) then if keep(current) then return false end if item.branded and ego(item) ~= ego(current) then return true end if ego(item) == ego(current) and estimate_ac(item) > estimate_ac(current) then return true end elseif upgrade(current) and er(item) <= maxer(current) then if base_ac(item) > base_ac(current) then return true end end end elseif subtype == "shield" then if keep(current) then return false end if current ~= nil and base_ac(item) >= base_ac(current) then if base_ac(item) > base_ac(current) then if item.branded then return true end else if item.branded and ego(item) ~= ego(current) then return true end if ego(item) == ego(current) and estimate_ac(item) > estimate_ac(current) then return true end end end end end if class == "weapon" then local match_found = false local upgrade_found = false local no_upgrade = false local upgrade_list = upgrade_list_for_weapon(item.name("base")) for inv in iter.invent_iterator:new(items.inventory()) do if class == inv.class(true) then if item.name("base") == inv.name("base") then match_found = true if keep(inv) then return false end if item.branded then if ego(item) ~= "unknown" and ego(item) == ego(inv) and plus_or_0(inv) >= plus_or_0(item) then return false end else if special(inv) or plus_or_0(inv) >= plus_or_0(item) then return false end end elseif upgrade_list[inv.name("base")] and (not twohanded(item) or twohanded(inv)) then upgrade_found = true if not upgrade(inv) then no_upgrade = true return false end end end end return match_found or (upgrade_found and not no_upgrade) end end add_autopickup_func(autopickup) function c_assign_invletter() need_inventory_check = true end function ready() if not initialized then crawl.more_autoclear(true) initialize() crawl.more_autoclear(false) initialized = true else if need_inventory_check then check_inventory() end end end stackable_classes = Set(stackable_classes) aux_subtypes = Set(aux_subtypes) twohanded_weapon_list = Set(twohanded_weapon_list) spriggan_onehanded_weapon_list = Set(spriggan_onehanded_weapon_list) body_armour_data = parse_body_armour_data() if you.genus() ~= "felid" then found["blowgun"] = false if you.genus() == "troll" or you.genus() == "ogre" then found["shield"] = false else found["buckler"] = false end end }