# HDA Default files include += HDAColors.rc include += PikaroSpoilers.rc include += HDamage.rc include += HDAForceMore.rc include += PikaroMiscDefaults.rc ################# # Magic options # ################# allow_self_target = prompt slot := spell_slot # d fghi klm o rs vwxz slot = animate dead:d slot += flight:f slot += regeneration:g slot += haste:h slot += deflect missiles:i slot += animate skeleton:k slot += delayed fireball:l slot += simulacrum:m slot += orb of destruction:o slot += repel missiles:r slot += stoneskin:s slot += condensation shield:v slot += swiftness:w slot += sublimation of blood:x slot += ozocubu.*armor:z :if you.class()=="Conjurer" or you.class()=="Wizard" then # abc e j mn p tu slot += magic dart:a slot += mystic blast:b slot += conjure flame:c slot += fireball:e slot += iron shot:j slot += mephitic cloud:q slot += force lance:n slot += poison cloud:p slot += battlesphere:t slot += freezing cloud:u :elseif you.class()=="Transmuter" then # ab i n p slot += beastly appendage:a slot += blade hands:b slot += ice form:i slot += spider form:p slot += sticks to snakes:n :elseif you.class()=="Fire Elementalist" then # a c e slot += flame tongue:a slot += conjure flame:c slot += fireball:e :elseif you.class()=="Air Elementalist" then # abc slot += shock:a slot += static discharge:b slot += lightning bolt:c :elseif you.class()=="Earth Elementalist" then # ab slot += sandblast:a slot += stone arrow:b :elseif you.class()=="Necromancer" then slot += pain:a :elseif you.class()=="Ice Elementalist" then slot += freeze:a slot += throw frost:b :end slot += .*:ABCDEFGHIJKLMNOPQRSTUVWXYZ ############# # Autofight # ############# auto_switch = false autofight_stop = 20 autofight_throw = false automagic_enable = true automagic_stop = 20 automagic_fight = false ############## # Autopickup # ############## : if (you.god():find("Trog")) then autopickup += $?!:"/}\ : else autopickup += $?!:"/}\| : end ae -= dangerous_item ############### # Autoexplore # ############### explore_stop -= stairs interrupt_travel -= hungry,sense_monster,mimic ############# # Interface # ############# view_delay = 0 skill_focus = toggle menu_colour ^= blue:(corpse|chunk) menu_colour ^= blue:bread ration menu_colour ^= blue:meat ration menu_colour ^= blue:jerk menu_colour ^= blue:jell menu_colour ^= blue:fruit menu_colour ^= blue:pizza menu_colour ^= darkgrey:inedible ############ # Messages # ############ msc := message_colour msc ^= mute:Things that are here: msc ^= mute:accepts your kill msc ^= mute:There is an open door here msc ^= mute:You open the door. more := force_more_message more ^= skill increases.*0 more ^= skill increases.*5 more ^= Shields skill increases to level 4 more ^= have mastered more ^= skill gains more ^= strange energies course more ^= a corruption grows more ^= begins to chant more ^= drag you back to the ground more -= cast banishment more -= cast paralyse more -= cast Torment more -= You.*teleport [^f] more -= Your amulet of stasis more -= You don't.* that spell ######################################################################################################################################################################################################################################## ############################################################################################## FUNCTIONS ############################################################################################################################# ######################################################################################################################################################################################################################################## ##################################################### # Ready Function - gets called when action required # ##################################################### { reminded_mindelay = {} function ready() crawl.enable_more(true) UpdateKnowledge() --if recentmessages ~= nil then newmessages = string.gsub(crawl.messages(100),recentmessages,"BREEEEEAK") else newmessages = "" end newmessages = crawl.messages(50) --debug("m", newmessages) if newmessages:find("finish memorising") or newmessages:find("unravels") then known_spells = init_spells() end if you.skill(weapon_skill) >= weapon_target_skill and reminded_mindelay[weapon_type] ~= true then crawl.mpr("Your wielded weapon is at mindelay!") sendkeys('m') reminded_mindelay[weapon_type] = true end check_safe_invisible(newmessages) --if newmessages:find("you kill") or newmessages:find("the.*dies") then -- debug("m","something died") --end AnnounceDamage() if hp <= max_hp * 0.25 and not warning_25 then crawl.mpr(string.format("HP at %i%%!",hp / max_hp * 100)) crawl.more() warning_25 = true warning_50 = true elseif hp <= max_hp * 0.5 and not warning_50 then crawl.mpr(string.format("HP at %i%%!",hp / max_hp * 100)) crawl.more() warning_50 = true end if hp > max_hp * 0.25 then warning_25 = false end if hp > max_hp * 0.5 then warning_50 = false end local casted_permanent_spells = false if options.autopick_on and you_safe then Autobutcher() casted_permanent_spells = PermanentSpells() end --SpoilerAlert() OpenSkills() if not casted_permanent_spells then FinishResting() end end function permanent_vars() vars = "" vars = vars .. stringify_var("safe_from_invisible",safe_from_invisible) vars = vars .. stringify_array("want_item",want_item) return vars end table.insert(chk_lua_save, permanent_vars) } ############# # Debugging # ############# { function DebugOutput() debug("status",you.status()) debug("safe",you_are_safe()) debug("save inv", safe_from_invisible) debug("ap", options.autopick_on) debug("apoff", autopickup_off_because) debug("energy",is_equipped("Weapon","staff of energy")) debug("energy_alt",is_alternative_weapon("staff of energy")) debug("missiles_have",stringify_array(missiles_have)) debug("equipped_at",stringify_array(equipped_at)) debug("have_chunks",stringify_array(have_chunks)) debug("rot",you_rot) debug("hunger",you_hunger) debug("last_butchered",last_butchered) debug("god",you.god()) debug("should_rest",you_should_rest) debug("debuffs",stringify_array(you_debuffs)) debug("debuffed",you_debuffed) debug("like_chunks",you_like_chunks) debug("see_corpses",see_corpses()) debug("over_corpses",over_corpses()) debug("see_skeletons",see_skeletons()) debug("over_skeletons",over_skeletons()) debug("you_spells",stringify_array(you_spells)) debug("want_item",stringify_array(want_item)) end } ###################### # Calculate Artprops # ###################### { function CalculateArtprops() local attr = { Str = 0, Dex = 0, Int = 0, HP = 0, MP = 0, Slay = 0, EV = 0, AC = 0 } local pluses = { rF = 0, rC = 0, Stlth = 0, rN = 0, MR = 0 } local actions = { Blink = 0, Inv = 0, Fly = 0 } local intr = { rMut = 0, rPois = 0, rElec = 0, SInv = 0, rCorr = 0, Regen = 0, Clar = 0, Ward = 0, Spirit = 0 } local ignore = { Contam = 0, channel = 0 } for it in inventory() do if it.equipped then local name = it.name() if name:find("{") then if it.class(true) == "weapon" then name = name:gsub(".*,","") name = name:gsub("}.*","") else name = name:gsub(".*{","") name = name:gsub("[},].*","") end for prop in name:gmatch("%S+") do propname = prop:gsub("%A","") if attr[propname] ~= nil then if prop ~= "+MP" then local count = tonumber(prop:gsub("%D",""),10) if prop:find("%+") then attr[propname] = attr[propname] + count elseif prop:find("%-") then attr[propname] = attr[propname] - count end end elseif pluses[propname] ~= nil then local count = prop:gsub("%a","") if count:find("%+") then count = count:len() elseif count:find("%-") then count = count:len() *-1 end pluses[propname] = pluses[propname] + count elseif actions[propname] ~= nil then actions[propname] = actions[propname] + 1 elseif intr[propname] ~= nil then intr[propname] = intr[propname] + 1 elseif ignore[propname] == nil then crawl.mpr(string.format("What is %s?",prop)) end end end end end local arrs = { ["Attributes: "] = attr, ["Pluses: "] = pluses, ["Actions: "] = actions, ["Intrinsics: "] = intr } for name,arr in pairs(arrs) do local outstr = name for stat,val in pairs(arr) do outstr = outstr .. stat .. ": " .. tostring(val) .. ", " end crawl.mpr(string.format("%s",outstr:gsub(", $",""))) end end } ######################### # Autotoggle Autopickup # ######################### { function ToggleAutopickupLastItem() local toggleitems_disappearing = { "potion", "scroll" } local toggleitems_permanent = { "ring", "wand", "amulet", "staff" } for _,name in pairs(toggleitems_disappearing) do if newmessages:find(name) then debug("n",name) end end for _,name in pairs(toggleitems_permanent) do if newmessages:find(name) then debug("n",name) end end end } ###################################### # Inventory Knowledge for Autothings # ###################################### { have_knowledge = false autopickup_slots = {cloak=true, helmet=true, gloves=true, boots=true} equipment_slots = {cloak="Cloak", helmet="Helmet", gloves="Gloves", boots="Boots", body="Armour", shield="Shield", weapon="Weapon"} itemcount = 0 have_chunks = {edible=nil, clean=nil, poisonous=nil} equipped_at = {cloak=nil, helmet=nil, gloves=nil, boots=nil, armour=nil, shield=nil, weapon=nil} missiles_have = {} have_poison_resistance = false you_race = you.race() you_like_chunks = you_race ~= "Mummy" and you_race ~= "Spriggan" and you_race ~= "Vampire" you_spells = { ["Regeneration"]=false, ["Deflect Missiles"]=false, ["Repel Missiles"]=false, ["Delayed Fireball"]=false, ["Sublimation of Blood"]=false, ["Animate Dead"]=false, ["Animate Skeleton"]=false, ["Simulacrum"]=false } you_buffs = { ["lich"]=false, ["regen"]=false, ["deflect missiles"]=false, ["repel missiles"]=false, ["delayed fireball"]=false } wait_debuffs = { "vulnerable", "confused", "corona", "exhausted", "petrifying", "silence", "marked", "barbs", "corroded", "slowed" } if want_item == nil then want_item = {} want_item["wand"] = { slowing=1, hasting=-1 } want_item["ring"] = { fire=2, ice=2 } want_item["evocable"] = { ["disc of storms"]=1 } want_item["deck"] = { plain=0, ornate=-1, legendary=-1 } end function UpdateKnowledge() itemcount = 0 missiles_have = {["bolt"]={},["arrow"]={},["sling bullet"]={},["needle"]={},["stone"]={},["large rock"]={},["throwing net"]={},["tomahawk"]={},["javelin"]={}} for it in inventory() do if it.class(true) == "missile" then missiles_have[it.subtype(true)][tostring(it.ego(true))] = true end itemcount = itemcount + 1 end you_status = you.status() you_can_cast = can_cast_spells() if you_can_cast then for spell,_ in pairs(you_spells) do you_spells[spell] = can_cast(spell) end for buff,_ in pairs(you_buffs) do you_buffs[buff] = (you_status:find(buff) ~= nil) end end you_debuffs = {} you_debuffed = false for _,debuff in pairs(wait_debuffs) do if you_status:find(debuff) ~= nil then you_debuffs[debuff] = true you_debuffed = true end end if you_like_chunks ~= 0 then have_chunks["edible"] = have_edible_chunks() have_chunks["clean"] = have_clean_chunks() have_chunks["poisonous"] = have_poisonous_chunks() end have_poison_resistance = you.res_poison() hp,max_hp = you.hp() mp,max_mp = you.mp() you_time = you.time() you_gourmand = you_are_gourmand() you_hunger = you.hunger() you_starving = (you_hunger == 0 and you_race ~= "Vampire") you_berserk = you.berserk() you_poisoned = you.poisoned() you_rot = you.rot() you_safe = you_are_safe() you_should_rest = should_rest() you_can_cast = can_cast_spells() you_god = you.god() local oldweapon = equipped_at["weapon"] for name,slot in pairs(equipment_slots) do equipped_at[name] = items.equipped_at(slot) end if equipped_at["weapon"] ~= oldweapon or weapon_target_skill == 0 then check_new_weapon() end have_knowledge = true end } #################### # Custom Autpickup # #################### { local strfind = string.find add_autopickup_func(function(it, name) if not have_knowledge then return nil end local class = it.class(true) if class == "missile" then return missiles_have[it.subtype(true)][tostring(it.ego(true))] end if class == "food" then if it.is_useless then return false end if strfind(name,"chunk") then local poisonous = strfind(name,"poison") if itemcount < 52 then if poisonous and not have_poison_resistance then return false else return true end else if poisonous and have_chunks["poisonous"] and have_poison_resistance then return true elseif not poisonous and have_chunks["clean"] then return true else return false end end else return true end end if class == "armour" then if it.is_useless then return false end local sub_type = it.subtype() if autopickup_slots[sub_type] then if not equipped_at[sub_type] then return true else return (it.artefact or it.branded or it.ego) end end end end) } ############### # Autobutcher # ############### { look_again = false last_butchered = nil function Autobutcher() if not you_like_chunks then return false end local oec = over_edible_corpse() local oeh = over_edible_chunk() local cec = can_eat_chunks() local wnc = want_new_chunks() if cec and ( oeh or have_chunks["edible"] ) then sendkeys("e") look_again = true elseif oec and ( cec or ( itemcount < 52 and ( wnc or not have_chunks["edible"] ) ) ) then sendkeys("c") last_butchered = you_time look_again = true elseif look_again then local itemlist = "" for it in floor_items() do itemlist = itemlist .. it.name_coloured() .. ", " end if itemlist ~= "" then crawl.mpr(string.format("Items here: %s",itemlist:sub(1,-3))) end look_again = false end end function want_new_chunks() return last_butchered==nil or you_time >= last_butchered + 1000 end function can_eat_chunks() if you_race=="Ghoul" then return you_hunger<4 or you_rot>0 or hp= spells.level(spell) then return true else return false end end function PermanentSpells() if you_can_cast then if not you_buffs["deflect missiles"] and you_spells["Deflect Missiles"] then sendkeys("zi") return true elseif not you_buffs["deflect missiles"] and not you_buffs["repel missiles"] and you_spells["Repel Missiles"] then sendkeys("zr") return true end if not you_buffs["delayed fireball"] and you_spells["Delayed Fireball"] then sendkeys("zl") return true end end return false end } ############################## # Rest up before autoexplore # ############################## { function FinishRestingThenAutoexplore() waiting_to_autoexplore = true but_dont_autoexplore = false end function TriggerFinishResting() waiting_to_autoexplore = true but_dont_autoexplore = true end waiting_to_autoexplore = false but_dont_autoexplore = false time_start_wait = 0 autoswitched_to_staff_of_energy = false tried_spells = {} function over_corpses() return remains_at(0,0,"corpse") end function see_corpses() local x,y for x=-8,8 do for y=-8,8 do if remains_at(x,y,"corpse") then return true end end end return false end function over_skeletons() return remains_at(0,0,"skeleton") end function see_skeletons() local x,y for x=-8,8 do for y=-8,8 do if remains_at(x,y,"skeleton") then return true end end end return false end function remains_at(x,y,what) if not you.see_cell_no_trans(x,y) then return false end local pile = items.get_items_at(x,y) if pile ~= nil then for it in iter.invent_iterator:new(pile) do if string.find(it.name(),what) then return true end end end return false end function FinishResting() if waiting_to_autoexplore and not PermanentSpells() then if time_start_wait == 0 then time_start_wait = you_time end if you_safe and not you_starving then crawl.enable_more(false) if you_can_cast then if not you_buffs["lich"] and you_spells["Sublimation of Blood"] and mp < max_mp and ((max_mp-mp)*3 <= 0.5*hp) then sendkeys("zx") return true elseif not you_buffs["lich"] and you_spells["Regeneration"] and hp < max_hp and not you_buffs["regen"] then sendkeys("zg") return true end if not tried_spells["Simulacrum"] and you_spells["Simulacrum"] and over_corpses() then sendkeys("zm") tried_spells["Simulacrum"] = true return true elseif not tried_spells["Animate Dead"] and you_spells["Animate Dead"] and (see_corpses() or see_skeletons()) then sendkeys("zd") tried_spells["Animate Dead"] = true return true elseif not tried_spells["Animate Skeleton"] and known_spells["Animate Skeleton"] then if over_corpses() then sendkeys("c") return true end if over_skeletons() and you_spells["Animate Skeleton"] then sendkeys("zk") tried_spells["Animate Skeleton"] = true return true end end end if is_equipped("weapon","staff of energy") and mp < max_mp and (have_chunks["edible"] or you_like_chunks==0) then sendkeys("v") elseif is_alternative_weapon("staff of energy") and mp < max_mp and (have_chunks["edible"] or you_like_chunks==0) then sendkeys("'") autoswitched_to_staff_of_energy = true elseif (you_should_rest and you_god ~= "Jiyva") or (you_should_rest and you_god == "Jiyva" and but_dont_autoexplore) then rest() else tried_spells = {} if autoswitched_to_staff_of_energy then sendkeys("'") autoswitched_to_staff_of_energy = false return true end waiting_to_autoexplore = false if you_time - time_start_wait > 10 then crawl.mpr(string.format("Total turns waited: %s",(you_time - time_start_wait)/10)) elseif but_dont_autoexplore then crawl.mpr("No need to wait!") end time_start_wait = 0 if not but_dont_autoexplore then crawl.enable_more(true) autoexplore() else but_dont_autoexplore = false end end else if you_time - time_start_wait > 10 then crawl.mpr(string.format("Total turns waited: %s",(you_time - time_start_wait)/10)) else reason = you_are_safe_reason() if reason == "unsafe" then crawl.mpr("There are monsters nearby!") elseif reason == "invis" then crawl.mpr("There are invisible monsters nearby!") elseif reason == "pois" then crawl.mpr("The poison in your blood would kill you!") elseif reason == "pillar" then crawl.mpr("You are pillardancing!") elseif you_starving then crawl.mpr("Starvation!") elseif you_berserk then crawl.mpr("You are berserking!") end end tried_spells = {} time_start_wait = 0 waiting_to_autoexplore = false but_dont_autoexplore = false end end end } ########################################## # Toggle Autopickup for last picked item # ########################################## { function ToggleAutopickupLast() last_item() end } ################################## # Auxiliary Function Definitions # ################################## { function debug(name,what) crawl.mpr(string.format("%s: %s",tostring(name),tostring(what))) end function stringify_array(arr) if type(arr) ~= 'table' then return type(arr) end local res = '{ ' for index, value in pairs(arr) do if type(value) == "table" then value = stringify_array(value) end if type(index) == "string" then res = res .. index .. ' = ' .. tostring(value) .. ', ' else res = res .. tostring(value) .. ', ' end end return res .. '}\n' end function stringify_var(varname, var) return varname .. " = " .. tostring(var) .. "\n" end function stringify_sorted_array(arr, order, aname) local res = aname .. " = { " for _, index in pairs(order) do res = res .. '["' .. string.format("%s",index) .. '"] = "' .. string.format("%s",arr[index]) .. '", ' end res = res .. "}\n" res = res .. aname .. "_order = { " for _, index in pairs(order) do res = res .. '"' .. string.format("%s",index) .. '", ' end res = res .. "}\n" return res end function you_are_safe() return safe_from_invisible and you.feel_safe() and (you.poison_survival() > 0) and not pillardancing and not you.berserk() end autopickup_off_because = false function check_safe_invisible(newmessages) if newmessages:find("eactivating autopickup") then autopickup_off_because = "monster" elseif newmessages:find("utopickup is now off") then autopickup_off_because = "user" end if not options.autopick_on and autopickup_off_because == "monster" then safe_from_invisible = false else safe_from_invisible = true end end function you_are_safe_reason() if not safe_from_invisible then return "invis" elseif not you.feel_safe() then return "unsafe" elseif not (you.poison_survival() > 0) then return "pois" elseif pillardancing then return "pillar" else return true end end function sendkeys(command) crawl.flush_input() crawl.sendkeys(command) crawl.flush_input() --coroutine.yield(true) end function should_rest() return you_poisoned or mp < max_mp or ( hp < max_hp and you_race~="Deep Dwarf" and ( you_race~="Vampire" or you_hunger>0 ) ) or you_debuffed end function you_are_gourmand() return you.gourmand() or you_race=="Troll" or you_race=="Kobold" or you_race=="Ghoul" or you_race=="Felid" end function autoexplore() sendkeys('o') end function rest() sendkeys('5') end function is_in_inventory(str) for it in inventory() do if string.find(it.name(), str) then return true end end return false end function inventory() return iter.invent_iterator:new(items.inventory()) end function last_item() local inv = items.inventory() debug("ni",inv[#inv].name()) end function floor_items() return iter.invent_iterator:new(you.floor_items()) end function is_equipped(where,str) if equipped_at[where] then return string.find(equipped_at[where].name(), str) else return false end end weapon_target_skill = 0 weapon_skill = "" weapon_type = "" function check_new_weapon() if equipped_at["weapon"] == nil then weapon_target_skill = 28 return true end local delay = equipped_at["weapon"].delay local old_weapon_skill = weapon_skill weapon_skill = equipped_at["weapon"].weap_skill local maxdelay = delay + math.floor(you.skill(weapon_skill) / 2) local mindelay = maxdelay / 2 if skill == "Short Blades" and mindelay > 5 then mindelay = 5 end if mindelay > 7 then mindelay = 7 end if skill == "Crossbows" and mindelay < 10 then mindelay = 10 end mindelay = math.max(mindelay,maxdelay - 14) if mindelay < 3 then mindelay = 3 end local old_weapon_target_skill = weapon_target_skill weapon_target_skill = (maxdelay - mindelay) * 2 weapon_type = equipped_at["weapon"].subtype() end function is_alternative_weapon(str) local slot_a = items.inslot(items.letter_to_index("a")) local slot_b = items.inslot(items.letter_to_index("b")) local weapon = equipped_at["weapon"] if slot_a and not slot_a.cursed then slot_a = slot_a.name() else return false end if slot_b and not slot_b.cursed then slot_b = slot_b.name() else return false end if weapon and not weapon.cursed then weapon = weapon.name() else return false end if weapon ~= slot_a and weapon ~= slot_b then return false end return (weapon == slot_a and string.find(slot_b,str)) or (weapon == slot_b and string.find(slot_a,str)) end --Escapes the special characters in a string for pattern matching function escape(str) --Escapes parens and dash "()-" local escaped = str:gsub('[%(%)%-]','\\%1') --Removes any coloration parts of the string return (escaped:gsub('<[^<]*>','')) end local need_skills_opened = true function OpenSkills() if you.turns() == 0 and need_skills_opened then need_skills_opened = false sendkeys("m") end end function init_spells() local spell_list = {} for _, spell_name in ipairs(you.spells()) do spell_list[spell_name] = true end return spell_list end known_spells = init_spells() }