###############
# Damage Calc #
###############
<
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")) then
max_hp_decreased = true
elseif (current_form:find("dragon") or
current_form:find("statue") or
current_form:find("tree") or
current_form:find("ice")) 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
--On losing health
if (current_hp < previous_hp) then
if current_hp <= (max_hp * 0.30) then
crawl.mpr("You take " .. hp_difference .. " damage, and have " .. current_hp .. "/" .. max_hp .. " hp.")
elseif current_hp <= (max_hp * 0.50) then
crawl.mpr("You take " .. hp_difference .. " damage, and have " .. current_hp .. "/" .. max_hp .. " hp.")
elseif current_hp <= (max_hp * 0.70) then
crawl.mpr("You take " .. hp_difference .. " damage, and have " .. current_hp .. "/" .. max_hp .. " hp.")
elseif current_hp <= (max_hp * 0.90) then
crawl.mpr("You take " .. hp_difference .. " damage, and have " .. current_hp .. "/" .. max_hp .. " hp.")
else
crawl.mpr("You take " .. hp_difference .. " damage, and have " .. current_hp .. "/" .. max_hp .. " hp.")
end
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
crawl.mpr("You regained " .. health_inturn .. " hp, and now have " .. current_hp .. "/" .. max_hp .. " hp.")
elseif current_hp <= (max_hp * 0.50) then
crawl.mpr("You regained " .. health_inturn .. " hp, and now have " .. current_hp .. "/" .. max_hp .. " hp.")
elseif current_hp <= (max_hp * 0.70) then
crawl.mpr("You regained " .. health_inturn .. " hp, and now have " .. current_hp .. "/" .. max_hp .. " hp.")
elseif current_hp <= (max_hp * 0.90) then
crawl.mpr("You regained " .. health_inturn .. " hp, and now have " .. current_hp .. "/" .. max_hp .. " hp.")
else
crawl.mpr("You regained " .. health_inturn .. " hp, and now have " .. current_hp .. "/" .. max_hp .. " hp.")
end
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
>
######################
## GENERAL SETTINGS ##
######################
small_more = true
show_more = false
default_manual_training = true
skill_focus = false
auto_butcher = full
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 = 10
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 .. "" .. color .. ">")
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_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)
}