#0.5th Version of Redear rc setting file (040419) #some functions was originated by P0wermode, HDA, Yermak, gammafunk, various, Yuuki, Alipheese, other. THX. #include += RandomTiles.rc include += HDamage.rc ###################### ## GENERAL SETTINGS ## ###################### small_more = true show_more = false default_manual_training = true skill_focus = false auto_butcher = true auto_eat_chunks = true easy_unequip = true equip_unequip = true #CharDump dump_item_origins = artefacts dump_skill_gains = true dump_vaults = true dump_turns_by_place = true tile_map_pixels=4 note_messages += Your scales start note_messages += magical essence is drained by the effort note_messages += tear in reality note_hp_percent = 30 note_all_skill_levels = true runrest_ignore_message += blood rots? away runrest_ignore_message += Your icy armour runrest_ignore_message += Your skin is crawling a little less runrest_ignore_message += infusion is running out runrest_ignore_message += shroud begins to fray runrest_ignore_message += You feel.*sick interrupt_memorise -= hp_loss interrupt_memorise -= monster ############## ## Explorer ## ############## travel_delay = -1 travel_key_stop = true #explore_delay = 10 explore_delay = -1 show_travel_trail = true explore_wall_bias = 20 explore_auto_rest = false rest_wait_both = false autofight_stop = 65 #################### ## AUTO INSCRIBES ## #################### ai := autoinscribe autoinscribe_cursed = false ai += bad_item.*potion:!q ai += potion.*mutation:!q ai += wand of heal wounds:!V ai += wand of teleportation:!V ai += wand of haste:!V ai += wand of invisibility:!V ai += trishula:!d ai += staff of air:rElec ai += staff of cold:rC+ ai += staff of death:rN+ ai += staff of energy:channel ai += staff of fire:rF+ ai += staff of poison:rPois ai += staff of power:MP+15 ai += staff of wizardry:Wiz+ ai += fire dragon (armour|hide):rF++ rC- ai += gold dragon (armour|hide):rC+ rF+ rPois ai += ice dragon (armour|hide):rC++ rF- ai += mottled dragon (armour|hide):rSticky ai += pearl dragon (armour|hide):rN+ ai += quicksilver dragon armour:MR+ ai += shadow dragon (armour|hide):Stlth++++ ai += steam dragon (armour|hide):rSteam ai += storm dragon (armour|hide):rElec ai += swamp dragon (armour|hide):rPois ai += troll (hide|leather armour):regen ai += (leather armour|mail|plate armour|robe|skin) of cold resistance:rC+ ai += (leather armour|mail|plate armour|robe|skin) of fire resistance:rF+ ai += (leather armour|mail|plate armour|robe) of magic resistance:MR+ ai += (leather armour|mail|plate armour|robe) of positive energy:rN+ ai += (leather armour|mail|plate armour) of poison resistance:rPois ai += troll leather armour of cold resistance:regen rC+ ai += troll leather armour of fire resistance:regen rF+ ai += plate armour of ponderousness:Speed- ai += robe of resistance:rC+ rF+ ai += robe of the archmagi:Spellpower+ ai += (barding|boots|buckler|cloak|gloves|hat|helmet|shield) of cold resistance:rC+ ai += (barding|boots|buckler|cloak|gloves|hat|helmet|shield) of fire resistance:rF+ ai += (barding|boots) of flight:Fly ai += (barding|boots) of stealth:Stlth+ ai += (barding|boots) of running:Speed+ ai += (barding|boots) of jumping:+Jump ai += (buckler|cloak|shield) of poison resistance:rPois ai += (buckler|shield) of positive energy:rN+ ai += (buckler|shield) of protection:AC+3 ai += (buckler|shield) of reflection:Reflect ai += (buckler|shield) of resistance:rC+, rF+ ai += (cloak|hat|helmet) of magic resistance:MR+ ai += (hat|helmet) of intelligence:Int+3 ai += (hat|helmet) of see invisible:SInv ai += cloak of darkness:+Inv ai += gloves of strength:Str+3 ai += gloves of dexterity:Dex+3 ai += gloves of archery:RNG Slay+4 ai += ring of fire:rF+ rC- ai += ring of flight:+Fly ai += ring of ice:rC+ rF- ai += ring of invisibility:+Inv ai += ring of loudness:Stlth- ai += ring of magical power:MP+9 ai += ring of poison resistance:rPois ai += ring of positive energy:rN+ ai += ring of protection from cold:rC+ ai += ring of protection from fire:rF+ ai += ring of protection from magic:MR+ ai += ring of see invisible:SInv ai += ring of stealth:Stlth+ ai += ring of sustain abilities:SustAb ai += ring of teleportation:+/*tele ai += ring of wizardry:Wiz+ ai += amulet of clarity:Clar ai += amulet of faith:Faith ai += amulet of guardian spirit:Spirit ai += amulet of rage:+Rage ai += amulet of regeneration:+Regen ai += amulet of resist corrosion:rCorr ai += amulet of resist mutation:rMut ai += amulet of stasis:Stasis ai += amulet of the gourmand:Gourm ai += amulet of warding:Ward rN+ ai += potions? of might:Str+5 DMG+1d10 | @q3 ai += potions? of agility:Stlth+ Dex+5 EV+5 | @q4 ai += potions? of brilliance:Archmagi Int+5 Wiz++ ai += potions? of resistance:rF+ rC+ rPois rElec rCorr ai += throwing net:+f ai += scroll of identify:@r1 ai += scroll of remove curse:@r2 ai += scroll of teleportation:@r3 ai += scroll of blinking:@r4 ai += potion of heal wounds:@q1 ai += potion of curing:@q2 ai += potion of haste:@q5 ai += potion of blood:@q9 item_slot ^= wand of digging:v : if you.god() == "Fedhas" then ai += fruits?:!e : end : if you.race() ~= "Mummy" then ai += weapon .*vamp:!w : end ################################## as := ability_slot as ^= End Trans: h as ^= Evoke Invis: i as ^= Turn Visibl: j as ^= Evoke Fligh: l as ^= Fly: l as ^= Stop Flying: m as ^= Evoke Telep: t as ^= Spit: q as ^= Breath: q ss := spell_slot ss ^= Apportation: g ss ^= Blink: d ss ^= Lesser Beck: e ss ^= Portal Proj: J ss ^= Teleport Ot: t ss ^= Warp Weapon: W ss ^= Passage of: z ss ^= Phase Shift: p ss ^= Summon Fore: F ss ^= ontrolled B: C ss ^= Control Tel: k ss ^= Song of Sla: y ss ^= Missiles: f ss ^= Flight: l ss ^= Regeneratio: R ss ^= Shroud of G: h ss ^= Spectral We: W ss ^= Ozocubu: h ss ^= Haste: H ss ^= Confuse: x ss ^= Tukima's Da: t ss ^= Invisibilit: I ss ^= Enslavement: v ss ^= Dazzling Sp: q ss ^= Animate Ske: b ss ^= Sublimation: Z ss ^= Corpse Rot: r ss ^= Control Und: U ss ^= Dispel Unde: u ss ^= Animate Dea: E ss ^= Borgnjor's : v ss ^= Sticks to S: s ss ^= Spider Form: O ss ^= Ice Form: I ss ^= Blade Hands: u ss ^= Statue Form: Y ss ^= Dragon Form: T ss ^= Stone Skin: s ss ^= Passwall: c ss ^= Lee's Rapid: l ss ^= Summon Butt: B ss ^= Aura of Abj: A ss ^= Summon Ligh: L ss ^= Conjure Fla: j ss ^= Mephitic Cl: m ss ^= Olgreb's To: t ss ^= Poisonous V: v ss ^= Cure Poison: w ss ^= Bolt: w ss ^= Fireball: e ####################### is := item_slot is ^= ring of protection from fire:f is ^= ring of protection from cold:c is ^= ring of protection from magic:m is ^= ring of poison resistance:o is ^= ring of see invisible:s is ^= ring of stealth:x is ^= ring of slaying:y is ^= of resist corrosion:g is ^= amulet of regeneration:r is ^= blowgun:q is ^= throwing net:Z is ^= scroll of remove curse:N is ^= scroll of identify:R is ^= scroll of teleportation:T is ^= scroll of blinking:B is ^= scroll of magic map:M is ^= potion of flight:l is ^= potion of curing:Q is ^= potion of haste:H is ^= wand of acid:A is ^= wand of digg:D is ^= wand of ensl:E is ^= wand of iceb:I is ^= wand of clou:O is ^= wand of para:P is ^= wand of scat:S is ^= wand of flam:V is ^= food:z is ^= box:U is ^= sack:W is ^= phial:X is ^= lamp:Y ################################### ### Species, Job, God conditions : if you.race() == "Ghoul" then auto_eat_chunks = false auto_butcher = full : else auto_eat_chunks = true : end : if true and (you.race() == "Spriggan" or you.race() == "Vine Stalker" or you.race() == "Gnoll") then default_autopickup = false : else default_autopickup = true : end : if you.race() == "Ghoul" then chunks_autopickup = true : else chunks_autopickup = false : end #: if you.race() == "Ghoul" or you.race() == "Felid" or you.race() == "Troll" or you.race() == "Kobold" then easy_eat_chunks = true #: end : if you.race() == "Ghoul" or you.race() == "Mummy" then ae += scrolls? of torment : end : if you.race() == "Formicid" then ae += >wand of dig : end : if you.race() == "Tengu" or you.race() == "Merfolk" or you.race() == "Barachi" or you.race() == "Octopode" then ae += >potions? of flight : end : if you.race() == "Vampire" or you.race() == "Mummy" or you.race() == "Ghoul" or you.race() == "Demonspawn" then ae += >scrolls? of holy word : end : if you.god() == "Trog" then ae += >potions? of brilliance ae += >potions? of berserk : end : if you.god() == "Zin" then ae ^= potions? of ambro : end : if you.god() == "Cheibriados"then default_autopickup = false force_more_message += comes? into view : end : if you.race() == "Barachi" then force_more_message += comes? into view : end : if you.god() == "Fedhas" then autoinscribe += fruit:!e : end : if false then ae += >potions? of brilliance ae += >book ae += >ring of int skill_focus = true : end ################################### ## FORCE MORES ## ## by P0werMode, Yermak ## ################################### more := force_more_message # dangerous monsters in sight # corrupters, temporary or permanent more += (giant eyeball|shining eye|cacodemon|neqoxec|corrupter|wretched star).*into view # tormentors more += (curse toe|curse skull|fiend|tzitzimitl|tormentor|mummy priest|greater mummy).*into view # damnators more += (deep elf high priest|deep elf sorcerer|draconian scorcher|draconian zealot|hell sentinel|hellion).*into view # summoners and displacers more += (deep elf demonologist|doom hound|draconian shifter|guardian serpent|ironbrand convoker|shadow demon).*into view # just plain strong more += (ancient lich|caustic shrike|iron giant|juggernaut|orb of fire).*into view # nasty statuses more += (ancient zyme|death cob|death drake|entropy weaver|flayed ghost|ghost moth|moth of wrath|starcursed mass|vault warden|warmonger).*into view # uniques or pan lords, also Killer Klown, Orb Guardian and some others more += (?-i:[A-Z]).* comes? into view # distortion weapons more += Space warps horribly around you more += Space bends around you more += hits you.*distortion more += warns you.*of distortion more += is wielding.*of distortion # invisible ghost moth more += watched by something # hit by Airstrike while flying more += The air twists around and violently strikes you in flight # ironbrand convoker's delayed summon more += begins to recite a word of recall # teleported onto exact same tile more += Your surroundings flicker # manual gone more += You have finished your manual # transmutation spell starts to run out more += Your transformation is almost over # bad mutations! (some will have the same text for multiple levels) # berserk more += You feel a little pissed off more += You feel angry more += You feel extremely angry at everything! # blurry vision more += Your vision blurs # teleportitis more += You feel weirdly uncertain more += You feel even more weirdly uncertain # deformed body more += Your body twists and deforms # frail more += You feel frail # --spell power +wiz more += Your connection to magic feels subdued more += Your connection to magic feels more subdued more += Your connection to magic feels nearly dormant # -wiz ++spell power more += You feel less in control of your magic more += You feel your magical power running wild # no device heal (only lvl 2-3) more += Your system mostly rejects artificial healing more += Your system completely rejects artificial healing # low regen (only lvl 3) more += You stop regenerating force_more_message += You have reached level force_more_message += You fall through a shaft force_more_message += You enter a teleport trap force_more_message += You are suddenly yanked force_more_message += interdimensional caravan force_more_message += distant snort force_more_message += Found a gateway leading out of the Abyss force_more_message += Found a gateway leading deeper into the Abyss force_more_message += Found .* abyssal rune of Zot force_more_message += Careful! force_more_message += You are starting to lose your buoyancy force_more_message += You miscast Flight force_more_message += filled with .* inner flame force_more_message += grabs you force_more_message += skill increases force_more_message += starts rolling force_more_message += looks more exp force_more_message += plume of calc force_more_message += vile air hits you force_more_message += engulfs you in water force_more_message += breathes miasma force_more_message += You feel your flesh start force_more_message += Found * staircase leading down force_more_message += You are engulfed in seething chaos force_more_message += You are slowing down force_more_message += You are confused force_more_message += fire storm spell force_more_message += Your guardian golem overheats force_more_message += offers itself force_more_message += volcano erupts force_more_message += Uskayaw prepares the audience for your solo force_more_message += Something reaches out for you force_more_message += You become entangled in the net runrest_stop_message += "Xom" force_more_message += Found a gate leading to another region of Pandemonium force_more_message += You found a shaft runrest_stop_message += You found a shaft flash_screen_message += You are slowing down : if you.xl() <= 7 then more += is wielding .*elec more += orc priest.*come more += centaur.* comes? into view : end : if you.xl() <= 11 then more += two-headed ogre.*come more += killer bee.* comes? into view : end : if you.xl() <= 15 then more += electric eel.* comes? into view : end : if you.race() == ("Demonspawn" or "Mummy" or "Vampire" or "Ghoul") then more += wielding .*holy more += (comes? into view|opens the).*Holy wrath more += Anubis guard.*(comes? into view|opens the) more += Black sun.*(comes? into view|opens the) more += Revenant.*(comes? into view|opens the) more += Tzitzimitl.*(comes? into view|opens the) more += Josephine.*(comes? into view|opens the) : end ### Portals force_more_message += ticking.*clock force_more_message += dying ticks force_more_message += distant snort force_more_message += coins.*counted force_more_message += tolling.*bell force_more_message += roar of battle force_more_message += creaking.*portcullis force_more_message += portcullis is probably force_more_message += wave of frost force_more_message += crackling.*melting force_more_message += hiss.*sand force_more_message += sound.*rushing water force_more_message += rusting.*drain force_more_message += drain falling apart force_more_message += heat about you force_more_message += falling.*rocks force_more_message += rumble.*avalanche of rocks force_more_message += crackle.*arcane power force_more_message += crackle.*magical portal force_more_message += distant wind force_more_message += whistling.*wind force_more_message += rapidly growing quiet # ------------------------ AUTOPICKUP EXCEPTIONS --------------------------- ae := autopickup_exceptions ae += = 22 then menu += $helpful:potions? of (lignification) : else menu += $survival:potions? of (lignification) : end ##################### Glyph colouring (console/log) glyph := item_glyph glyph = glyph += $bad:.*evil_item.* glyph += $verybad:[^n] cursed.* glyph += inventory:$verybad:[^n] cursed.* glyph += inventory:$important:.*equipped.* glyph += $useless:.*useless_item.* glyph += $artefact:.*artefact.* glyph += $useless:amulet of inaccuracy glyph += $magic:amulet of (guardian spirit|stasis|warding) glyph += $good:amulet of (faith|rage|resist corrosion) glyph += $verygood:amulet of (clarity|regeneration|resist mutation|the gourmand) glyph += $good:\+.*(buckler|shield|mail|armour|robe|hat|helmet) glyph += $magic:.*(runed|dyed|shiny|glowing|enchanted).*(armour|weapon|shield).* glyph += $survival:disc of storms glyph += $dangerous:tome of Destruction glyph += $magic:box of beasts glyph += $useless:lantern of shadows glyph += $helpful:stone of tremors glyph += $survival:fan of gales glyph += $helpful:lamp of fire glyph += $helpful:phial of floods glyph += $magic:sack of spiders glyph += $helpful:phantom mirror glyph += $magic:crystal ball of energy glyph += $bad:evil_eating glyph += $dangerous:rot-inducing glyph += $dangerous:poisonous glyph += $useless:inedible glyph += $good:(bread ration|meat ration) glyph += $good:preferred glyph += $helpful:(corpse|chunk) glyph += $dangerous:mutagenic glyph += $dangerous:potions? of (berserk|mutation) glyph += $good:potions? of (flight|restore) glyph += $helpful:potions? of (agility|brilliance|invisibility|resistance) glyph += $verygood:potions? of curing glyph += $survival:potions? of (haste|heal wounds|cancellation|might) glyph += $important:potions? of (beneficial|cure mutation|experience|gain) glyph += $magic:potions? of magic glyph += $bad:scrolls? of torment glyph += $dangerous:scrolls? of (noise|random|immolation) glyph += $helpful:scrolls? of (amnesia|holy word|identify|remove curse) glyph += $good:scrolls? of (silence|summoning|vulnerability) glyph += $verygood:scrolls? of (brand|enchant|magic mapping|recharging) glyph += $survival:scrolls? of (blinking|teleportation|fog|acquirement|fear) glyph += $useless:wand of (flame|frost|magic darts|random effects) glyph += $helpful:wand of (confusion|enslavement|paralysis|polymorph|slowing) glyph += $good:wand of (digging|disintegration|draining) glyph += $verygood:wand of (cold|fire|fireball|lightning) glyph += $survival:wand of (teleportation|invisibility|heal wounds|hasting) glyph += $verybad:ring of \-.*(dexterity|evasion|intelligence|protection|slaying|strength) glyph += $helpful:ring of (fire|ice) glyph += $useless:ring of (flight|loudness) glyph += $good:ring of (.*evasion|invisibility|magical power|.*protection|stealth|sustain abilities|wizardry) glyph += $verygood:ring of (poison resistance|protection from cold|protection from fire|protection from magic|see invisible) glyph += $important:ring of (teleport|.*slaying|sustain abilities) ##################### Stats colouring (numbers) status_caption_colour = green hp_colour = 100:lightgreen, 90:green, 60:yellow, 30:lightred, 15:red stat_colour = 125:white, 50:lightgreen, 14:green, 9:yellow, 6:lightred, 3:red mp_colour = 100:lightcyan, 85:cyan, 60:lightblue, 30:blue, 15:red # Tags: stats, colours, colouring, menu, glyphs, hp, mp, health, mana, ##################### ##################### End of colouring ##################### ################################################################## ## Force mores by gammafunk, modificate by P0werMode ## ################################################################## # Taken from gammafunk's force_mores.lua and modified # Force more messages on certain monsters' appearance depending on the player's # current stats. Only monsters not already included in the constant setting # earlier in the .rc file are here. I hope it works, ha ha. { last_turn = you.turns() -- Conditions are in the fm_patterns array. For now only one condition -- per monster is allowed until (if) I get better at lua to modify -- the script further. Each array entry works as follows: -- pattern = monster name -- cond = attribute to check; behaviour is defined later on -- cutoff = if attribute's value is equal or higher, don't force more for these -- name = an identifier for the entry in the array fm_patterns = { -- early threats {pattern = "adder|gnoll", cond = "xl", cutoff = 5, name = "XL5"}, -- early poisonous threats -- {pattern = "worker ant|scorpion", cond = "xl", cutoff = 7, name = "XL7"}, -- the frog of doom and a merry lizard {pattern = "spiny frog|komodo dragon", cond = "xl", cutoff = 12, name = "XL12"}, -- biggest lair threats {pattern = "death yak|dire elephant|black mamba|wolf spider", cond = "xl", cutoff = 15, name = "XL15"}, -- biggest orc threat {pattern = "orc warlord", cond = "xl", cutoff = 17, name = "XL17"}, -- no rF {pattern = "fire giant|balrug", cond = "rf", cutoff = 1, name = "rF1"}, -- no rC {pattern = "ice giant|white draconian|blizzard demon|azure jelly", cond = "rc", cutoff = 1, name = "rC1"}, -- no rElec {pattern = "spark wasp|titan", cond = "relec", cutoff = 1, name = "rE1"}, -- no rPois {pattern = "swamp drake|swamp dragon|green draconian|golden dragon", cond = "rpois", cutoff = 1, name = "rP1"}, -- no rCorr (boolean) {pattern = "rust devil|acid blob", cond = "rcorr", cutoff = 999, name = "rA1"}, -- low MR (MR not directly exposed to clua yet) -- {pattern = "basilisk|deep elf archer|bog body|faun|ogre mag", cond = "mr", cutoff = 40, name = "MR1"}, -- {pattern = "orc sorcerer|siren|satyr|great orb of eyes", cond = "mr", cutoff = 80, name = "MR2"}, -- {pattern = "merfolk avatar|vault sentinel|vampire knight|golden eye|wizard|sphinx", cond = "mr", cutoff = 120, name = "MR3"}, -- no rN {pattern = "deep elf death mag|eidolon", cond = "rn", cutoff = 1, name = "rN1"}, -- airstrike (boolean) {pattern = "wind drake|spriggan air mag", cond = "fly", cutoff = 999, name = "fly"}, -- HP {pattern = "annihilator", cond = "mhp", cutoff = 120, name = "HP3"} } -- end fm_patterns active_fm = {} -- Set to true to get a message when the fm change notify_fm = false function init_force_mores() for i,v in ipairs(fm_patterns) do active_fm[#active_fm + 1] = false end end function update_force_mores() local activated = {} local deactivated = {} local hp, maxhp = you.hp() for i,v in ipairs(fm_patterns) do local msg = "(" .. v.pattern .. ").*into view" local action = nil local fm_name = v.pattern if v.name then fm_name = v.name end if not v.cond and not active_fm[i] then action = "+" elseif v.cond == "xl" then if active_fm[i] and you.xl() >= v.cutoff then action = "-" elseif not active_fm[i] and you.xl() < v.cutoff then action = "+" end elseif v.cond == "rf" then if active_fm[i] and you.res_fire() >= v.cutoff then action = "-" elseif not active_fm[i] and you.res_fire() < v.cutoff then action = "+" end elseif v.cond == "rc" then if active_fm[i] and you.res_cold() >= v.cutoff then action = "-" elseif not active_fm[i] and you.res_cold() < v.cutoff then action = "+" end elseif v.cond == "relec" then if active_fm[i] and you.res_shock() >= v.cutoff then action = "-" elseif not active_fm[i] and you.res_shock() < v.cutoff then action = "+" end elseif v.cond == "rpois" then if active_fm[i] and you.res_poison() >= v.cutoff then action = "-" elseif not active_fm[i] and you.res_poison() < v.cutoff then action = "+" end elseif v.cond == "rcorr" then if active_fm[i] and you.res_corr() then action = "-" elseif not active_fm[i] and you.res_corr() then action = "+" end elseif v.cond == "rn" then if active_fm[i] and you.res_draining() >= v.cutoff then action = "-" elseif not active_fm[i] and you.res_draining() < v.cutoff then action = "+" end elseif v.cond == "fly" then if active_fm[i] and you.flying() then action = "-" elseif not active_fm[i] and you.flying() then action = "+" end elseif v.cond == "mhp" then if active_fm[i] and maxhp >= v.cutoff then action = "-" elseif not active_fm[i] and maxhp < v.cutoff then action = "+" end end if action == "+" then activated[#activated + 1] = fm_name elseif action == "-" then deactivated[#deactivated + 1] = fm_name end if action ~= nil then local opt = "force_more_message " .. action .. "= " .. msg crawl.setopt(opt) active_fm[i] = not active_fm[i] end end if #activated > 0 and notify_fm then mpr("Activating force_mores: " .. table.concat(activated, ", ")) end if #deactivated > 0 and notify_fm then mpr("Deactivating force_mores: " .. table.concat(deactivated, ", ")) end end local last_turn = nil function force_mores() if last_turn ~= you.turns() then update_force_mores() last_turn = you.turns() end end init_force_mores() } ################################################################## ## Force mores (end) ## ################################################################## ################################################################## ## Speedrun_rest by gammafunk (on 25 Jun 2017) ## ################################################################## { -- See README.md for documentation. -- How many turns to rest at max. num_rest_turns = 30 -- If true, look for a foot item inventory slot and use fallback_slot if we -- can't find a ration. If false, always use fallback_slot. automatic_slot = true -- Slot where you keep your slow swing item. fallback_slot = "c" -- Set to true to have Na characters always walk instead of item swing if -- they're able to walk slowly. This is not as turncount efficient for non-Chei -- worshipers, but some Na players may prefer it over having to change the -- wielded weapon. naga_always_walk = false -- Delay in milliseconds before sending the next walk command. Makes the -- visuals a bit less jarring when using walk resting. Set to 0 to disable. walk_delay = 50 -- To have the multi-turn rest ignore status change messages, add an entry here -- giving the pattern of the message you'd like to ignore. The entries below -- cover the transition messages from the regen spell, Trog's hand, and poison -- status. The key should be the status that's seen in the output of -- `you.status()` when the status is active, and the value should be a single -- pattern string or an array of pattern strings matching the message you'd -- like to ignore. See the lua string library manual for details on making -- patterns. status_messages = { ["poisoned"] = {"You feel[^%.]+sick%.", "You are no longer poisoned%."}, ["regenerating"] = {"You feel the effects of Trog's Hand fading%.", "Your skin is crawling a little less now%."} } --end status_messages -- Like status_messages above, but for arbitrary messages. Any message matching -- one of these patterns is ignored. ignore_messages = { --RandomTiles messages "Trog roars: Now[^!]+!+", "Sif Muna whispers: Become[^!]+!+", "[^:]+ says: Become[^!]+!+", --Debug messages "Dbg:.*", } -- end ignore_messages -- NOTE: No configuration past this point. ATT_NEUTRAL = 1 version = 0.15 if crawl.version then version = tonumber(crawl.version("major")) end los_range = version >= 0.17 and 7 or 8 -- Wrapper of crawl.mpr() that prints text in white by default. if not mpr then mpr = function (msg, color) if not color then color = "white" end crawl.mpr("<" .. color .. ">" .. msg .. "") end end function control(c) return string.char(string.byte(c) - string.byte('a') + 1) end function delta_to_vi(dx, dy) local d2v = { [-1] = { [-1] = 'y', [0] = 'h', [1] = 'b'}, [0] = { [-1] = 'k', [1] = 'j'}, [1] = { [-1] = 'u', [0] = 'l', [1] = 'n'}, } -- hack return d2v[dx][dy] end function reset_rest() if not rstate then rstate = { } rstate.set_slot = false rstate.dir_x = nil rstate.dir_y = nil end rstate.last_acted = nil rstate.wielding = false rstate.resting = false rstate.num_turns = nil rstate.rest_start = nil rstate.start_hp = nil rstate.start_status = { } rstate.start_message = nil end function abort_rest(msg) if msg then mpr(msg, "lightred") end reset_rest() end function crawl_message(i) local msg = crawl.messages(i):gsub("\n", "") msg = msg:gsub("^%c* *", "") msg = msg:gsub(" *%c*?$", "") return msg end function record_status() -- Record starting status to track any status changes. rstate.start_status = { } local status = you.status() for s,_ in pairs(status_messages) do if status:find(s) then rstate.start_status[s] = true end end rstate.start_message = get_last_message() end function in_water() return view.feature_at(0, 0):find("water") and not you.status("flying") end function get_last_message() local rest_type = get_rest_type() local in_water = in_water() -- Ignore these movement messages when walking. local move_patterns = {"There is a[^%.]+here.", "Things that are here:.*", "Items here:.*"} for i = 1,200 do local msg = crawl_message(i) for s,_ in pairs(rstate.start_status) do if type(status_messages[s]) == "table" then for _,p in ipairs(status_messages[s]) do msg = msg:gsub(p, "") end else msg = msg:gsub(status_messages[s], "") end end if rest_type == "walk" then for _,p in ipairs(move_patterns) do -- Also remove any whitespace. msg = msg:gsub(" *" .. p .. " *", "") end end msg = msg:gsub(" *Beep! [^%.]+%. *", "") for _,p in ipairs(ignore_messages) do msg = msg:gsub(p, "") end if msg ~= "" then return msg end end return nil end function wield_swing_item() rstate.wielding = true rstate.last_acted = you.turns() record_status() crawl.sendkeys("w*" .. c_persist.swing_slot) end function find_swing_slot() rstate.set_slot = true if not automatic_slot then c_persist.swing_slot = fallback_slot return end c_persist.swing_slot = nil for _,item in ipairs(items.inventory()) do if item.class() == "Comestibles" or item.class() == "Books" or item.class() == "Wands" or item.class() == "Missiles" or item.class() == "Miscellaneous" or (item.class() == "Hand Weapons" and (item.subtype():find("bow") or item.subtype():find("sling") or item.subtype():find("crossbow") or item.subtype():find("blowgun"))) then c_persist.swing_slot = items.index_to_letter(item.slot) break end end if not c_persist.swing_slot then c_persist.swing_slot = fallback_slot end end function swing_item_wielded() local weapon = items.equipped_at("Weapon") return weapon and c_persist.swing_slot ~= nil and weapon.slot == items.letter_to_index(c_persist.swing_slot) end function hostile_in_los() local have_t1 = false for x = -los_range,los_range do for y = -los_range,los_range do m = monster.get_monster_at(x, y) if m and not m:is_safe() then return true end end end return false end function ponderous_level() local level = 0 for _,item in ipairs(items.inventory()) do local ego = item.ego() if item.equipped and ego == "ponderousness" then level = level + 1 end end return level end -- XXX See if we can move at least some of this into clua, since it's -- recreating play_movement_speed() and player_speed(). The aim is to determine -- if slow move is more regen-efficient and that the saving is worth the -- hassle, this calculates the minimum move speed, which can normally vary at -- random from randomized delay (e.g. water) and the many uses of -- div_rand_round(). function player_move_speed() if you.transform() == "tree" then return 0 end local in_water = in_water() local walk_water = you.race() == "Merfolk" or you.race() == "Octopode" or you.race() == "Barachi" or you.god() == "Beogh" and you.piety_rank() == 5 or you.transform == "ice" -- This is player action speed, based on things that affect all actions. local player_speed = 10 if you.status("slowed") then player_speed = math.floor(player_speed * 3 / 2) end if you.status("berserking") and you.god() ~= "Cheibriados" or you.status("hasted") then player_speed = math.floor(player_speed * 2 / 3) end if you.transform() == "statue" or you.status("petrifying") then player_speed = math.floor(player_speed * 3 / 2) end if in_water and not walk_water then player_speed = math.floor(player_speed * 13 / 10) end -- This is the base player movement speed given all things that affect only -- movement. local move_speed = 10 if you.transform() == "bat" then move_speed = 5 elseif you.transform() == "pig" then move_speed = 7 elseif you.transform() == "porcupine" or you.transform == "wisp" then move_speed = 8 elseif in_water and (you.transform() == "hydra" or you.race() == "Merfolk") then move_speed = 6 elseif you.race() == "Tengu" and you.status("flying") then move_speed = 9 end local boots = items.equipped_at("Boots") local running_level = 0 if boots and not boots.is_melded and boots.ego() and boots.ego() == "running" then running_level = 1 end move_speed = move_speed - running_level move_speed = move_speed + ponderous_level() if you.god() == "Cheibriados" then -- Calculate this based on the minimum piety at the observed rank, -- since we can't know the true piety level. local piety_breaks = { 1, 30, 50, 75, 100, 120, 160 } move_speed = move_speed + 2 + math.floor(math.min(piety_breaks[you.piety_rank() + 1] / 20, 8)) end if you.status("frozen") then move_speed = move_speed + 4 end if you.status("grasped by roots") then move_speed = move_speed + 3 end local speed_mut = you.mutation("speed") local slow_mut = you.mutation("slowness") if speed_mut > 0 then move_speed = move_speed - speed_mut - 1 elseif slow_mut > 0 then move_speed = math.floor(move_speed * (10 + slow_mut * 2) / 10) end if not in_water and you.status("sluggish") then if move_speed >= 8 then move_speed = math.floor(move_speed * 3 / 2) elseif move_speed == 7 then move_speed = math.floor(7 * 6 / 5) end elseif not in_water and you.status("swift") then move_speed = math.floor(move_speed * 3 / 4) end if move_speed < 6 then move_speed = 6 end return math.floor(player_speed * move_speed / 10) end function get_rest_type() if you.race() == "Naga" and naga_always_walk or you.god() == "Cheibriados" or (not swing_item_wielded() and not weapon_can_swap()) then return "walk" else return "item" end end function bad_to_act() local hp, mhp = you.hp() local rest_type = get_rest_type() -- Stop multiple turn action when our hp recovers. if rstate.rest_start and rstate.start_hp < mhp and hp == mhp then mpr("HP restored.") reset_rest() return true end if you.status("manticore barbs") then abort_rest("You must remove the manticore barbs first.") return true end if you.hunger_name() == "fainting" or you.hunger_name() == "starving" then abort_rest("You need to eat!") return true end if hostile_in_los() then if not rstate.rest_start then abort_rest("You can't rest with a hostile monster in view!") else abort_rest() end return true end -- If any unrecognized message occurs, assume we need to stop resting. if rstate.last_acted then local msg = get_last_message() if not msg then abort_rest("Unable to find a previous message!") return true end local wield_pt = "^ *" .. c_persist.swing_slot .. " - .+[%)}] *$" local swing_pt = "^ *You swing at nothing%. *$" local pattern = rstate.wielding and wield_pt or swing_pt if (rest_type == "item" and not msg:find(pattern)) or rest_type == "walk" and msg ~= rstate.start_message then abort_rest() return true end end if rest_type == "walk" and player_move_speed() <= 10 then abort_rest("You cannot walk slowly right now!") return true end return false end function feat_is_open(feat) local fname = feat:lower() -- Unique substrings that identify solid features. local solid_features = {"wall", "grate", "tree", "mangrove", "endless_lava", "open_sea", "statue", "idol", "malign_gateway", "sealed_door", "closed_door", "runed_door", "explore_horizon"} for i,p in ipairs(solid_features) do if fname:find(p) then return false end end return true end function safe_walk_pos(x, y) local in_water = in_water() local pos_is_water = view.feature_at(x, y):find("water") -- Don't allow walking out of water if we're in water return (in_water and pos_is_water -- Don't allow walking into water if we're not in it or not in_water and not pos_is_water) -- Require the destination to be safe. and view.is_safe_square(x, y) end function safe_swing_pos(x, y) return not monster.get_monster_at(x, y) and feat_is_open(view.feature_at(x,y)) end function safe_direction(x, y) if get_rest_type() == "walk" then return safe_walk_pos(x, y) else return safe_swing_pos(x, y) end end function weapon_can_swap() local weapon = items.equipped_at("Weapon") if not weapon then return true end if weapon.cursed then return false end local ego = weapon.ego() -- Some unrands like Plut. sword have no ego. if ego and (ego == "vampirism" or ego == "distortion" and you.god() ~= "Lugonu") then return false end if weapon.artefact then local artp = weapon.artprops return not (artp["*Contam"] or artp["*Curse"] or artp["*Drain"]) end return true end function get_safe_direction() local have_t1 = false for x = -1,1 do for y = -1,1 do if (x ~= 0 or y ~= 0) and safe_direction(x, y) then return x, y end end end return nil end function do_resting() -- Our first turn of resting. if not rstate.rest_start then record_status() rstate.rest_start = you.turns() rstate.start_hp = you.hp() end rstate.last_acted = you.turns() local rest_type = get_rest_type() if rest_type == "item" then crawl.sendkeys(control(delta_to_vi(rstate.dir_x, rstate.dir_y))) else local cur_x = rstate.dir_x local cur_y = rstate.dir_y -- Save the return direction as our next direction. rstate.dir_x = -rstate.dir_x rstate.dir_y = -rstate.dir_y crawl.sendkeys(delta_to_vi(cur_x, cur_y)) crawl.delay(walk_delay) end end function one_turn_rest() rstate.resting = true rstate.num_turns = 1 end function start_resting() rstate.resting = true rstate.num_turns = num_rest_turns end function set_swing_slot() crawl.formatted_mpr("Enter an slot letter for the swing item: ", "prompt") local letter = crawl.c_input_line() local index = items.letter_to_index(letter) if not index or index < 0 then mpr("Must be a letter (a-z or A-Z)!", "lightred") return end c_persist.swing_slot = letter rstate.set_slot = true mpr("Set swing slot to " .. letter .. ".") end function speedrun_rest() local rest_type = get_rest_type() if rest_type == "item" and (not c_persist.swing_slot or you.turns() == 0 and not rstate.set_slot) then find_swing_slot() end if not rstate.resting then return end -- Only act once per turn. if rstate.last_acted == you.turns() then -- An error happened with the 'w' command if rstate.wielding and not swing_item_wielded() then abort_rest("Unable to wield swing item on slot " .. c_persist.swing_slot .. "!") end return end if rstate.last_acted and rstate.rest_start and rstate.last_acted + 1 >= rstate.rest_start + rstate.num_turns then reset_rest() return end if bad_to_act() then return end if rest_type == "item" and not swing_item_wielded() then wield_swing_item() return end rstate.wielding = false if not rstate.dir_x -- Don't try to reuse our position if we were walk resting and did -- something inbetween our last rest. or swing_type == "walk" and rstat.last_acted ~= you.turns() - 1 or not safe_direction(rstate.dir_x, rstate.dir_y) then rstate.dir_x, rstate.dir_y = get_safe_direction() if not rstate.dir_x then abort_rest("No safe direction found!") return end end do_resting() end reset_rest() } ################################################################## ## Speedrun_rest (end) ## ################################################################## ################################################################### ## Automatic exclusion marking by Ultraviolent4 (finding traps) ## ################################################################### { function c_answer_prompt(prompt) if prompt == "Really walk into a travel-excluded area?" then return true end if prompt == "Really fly into a travel-excluded area?" then return true end if prompt == "Really swim into a travel-excluded area?" then return true end end } { function mark_monsters() los = you.los() for i = -los,los do for j = -los,los do m = monster.get_monster_at(i,j) if m and (not should_ignore_monster(m)) then local feat = view.feature_at(i,j) if not should_ignore_feature(feat) then travel.set_exclude(i,j,0) end end end end end } { function mark_feet() local feat = view.feature_at(0,0) if not should_ignore_feature(feat) then travel.set_exclude(0,0,0) end end } { function should_ignore_monster(m) local name = m:name() return name:find("spire") or name:find("fulminant") or name:find("battlesphere") end } { function should_ignore_feature(feat) return feat_is_stair(feat) or feat_is_door(feat) or feat:find("altar") or feat:find("shop") or feat:find("portal") or feat:find("arch") or feat:find("leading out of this place") or feat:find("gate") end } { function feat_is_door(feat) return feat:find("door") end } { function feat_is_stair(feat) return (feat:find("stone_stairs_up") or (feat:find("exit_") and (feat == "exit_hell" or feat == "exit_vaults" or feat == "exit_zot" or feat == "exit_slime_pits" or feat == "exit_orcish_mines" or feat == "exit_lair" or feat == "exit_crypt" or feat == "exit_snake_pit" or feat == "exit_elven_halls" or feat == "exit_tomb" or feat == "exit_swamp" or feat == "exit_shoals" or feat == "exit_spider_nest" or feat == "exit_depths" or feat == "exit_temple" or feat == "exit_dungeon")) or feat == "escape_hatch_up" or feat:find("stone_stairs_down") or feat:find("enter_") or feat == "escape_hatch_down") end } ################################################################## ## Automatic exclusion marking (end) ## ################################################################## #--------------RUN LUA FUNCTIONS { local need_skills_opened = true; function ready() -- Skill menu at game start (by rwbarton) if you.turns() == 0 and need_skills_opened then need_skills_opened = false; crawl.sendkeys("m"); end --[[ -- Automatic exclusion marking, finding a traps (by Ultraviolent4) mark_monsters(); mark_feet(); --]] force_mores() speedrun_rest() AnnounceDamage() end } #tile_player_tile = mons:Aizul #tile_player_tile = mons:Agnes #tile_player_tile = mons:Boris #tile_player_tile = mons:Murray #tile_player_tile = mons:Donald #tile_player_tile = mons:minotaur #tile_player_tile = tile:octopode_1 #tile_player_tile = mons:Shambling mangrove # Use a custom tile when playing a Felid : if you.race() == "Felid" then tile_player_tile = tile:felid_3 : end : if you.race() == "Vampire" then auto_eat_chunks = false auto_butcher = true ae += >scrolls? of holy word ai += potion of heal wounds:@q9 ai += potion of blood:@q1 tile_player_tile = mons:Vampire #tile_player_tile = mons:Vampire knight #tile_player_tile = mons:Jory : end : if you.race() == "Demigod" then auto_eat_chunks = true auto_butcher = true tile_player_tile = mons:Azrael : end tile_realtime_anim = true #automagic_enable = false automagic_enable = true If true, the autofight function will resort to casting an assigned spell at a target. Initial spell slot is a. automagic_slot = a Setting this changes the initial spell slot for automagic. Can be changed for games in progress in-game by setting a macro to call ===am_set_spell. automagic_fight = true Setting this to true causes melee combat when trying to cast a spell that you either do not have enough magic points for, or are below the set threshold. If false, a message will appear and no further action is taken. automagic_stop = 30 Similar to autofight_stop, if magic points are below this number (percentage of total), casting is prevented. What happens depends on automagic_fight setting. ## Pickup aux armour you haven't found yet. ## Also picks up ego/artefact aux armour if you can wear it. ## Doesn't pick up shields or body armour. { local function autopickup(it, name) local class = it.class(true) if it.is_useless then return false end if class == "armour" then local good_slots = {cloak="Cloak", helmet="Helmet", gloves="Gloves", boots="Boots"} st, _ = it.subtype() if good_slots[st] ~= nil and items.equipped_at(good_slots[st]) == nil then return true elseif st ~= "body" and st ~= "shield" and (it.artefact or it.branded) then return true end end return nil end add_autopickup_func(autopickup) }