Initial commit

This commit is contained in:
2025-10-07 08:39:41 -05:00
commit 09ee6feaed
15 changed files with 461 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
.env
.venv/
uv.lock

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.13

5
basic_symbols.rc Normal file
View File

@@ -0,0 +1,5 @@
SYMBOLS=S_magic_portal:\x38
SYMBOLS=S_rust_trap:\x38
SYMBOLS=S_water:\x7E
SYMBOLS=S_pool:\x7E
SYMBOLS=S_lava:\x7E

22
color_glyphs.rc Normal file
View File

@@ -0,0 +1,22 @@
OPTIONS=glyph:G_vwall_mines/U+2502/brown
OPTIONS=glyph:G_hwall_mines/U+2500/brown
OPTIONS=glyph:G_tlcorn_mines/U+250c/brown
OPTIONS=glyph:G_trcorn_mines/U+2510/brown
OPTIONS=glyph:G_blcorn_mines/U+2514/brown
OPTIONS=glyph:G_brcorn_mines/U+2518/brown
OPTIONS=glyph:G_crwall_mines/U+253C/brown
OPTIONS=glyph:G_tuwall_mines/U+2534/brown
OPTIONS=glyph:G_tdwall_mines/U+252C/brown
OPTIONS=glyph:G_tlwall_mines/U+2524/brown
OPTIONS=glyph:G_trwall_mines/U+251C/brown
OPTIONS=glyph:G_vwall_knox/U+2502/yellow
OPTIONS=glyph:G_hwall_knox/U+2500/yellow
OPTIONS=glyph:G_tlcorn_knox/U+250c/yellow
OPTIONS=glyph:G_trcorn_knox/U+2510/yellow
OPTIONS=glyph:G_blcorn_knox/U+2514/yellow
OPTIONS=glyph:G_brcorn_knox/U+2518/yellow
OPTIONS=glyph:G_crwall_knox/U+253C/yellow
OPTIONS=glyph:G_tuwall_knox/U+2534/yellow
OPTIONS=glyph:G_tdwall_knox/U+252C/yellow
OPTIONS=glyph:G_tlwall_knox/U+2524/yellow
OPTIONS=glyph:G_trwall_knox/U+251C/yellow

14
hdf-37.rc Normal file
View File

@@ -0,0 +1,14 @@
{% include "main.rc" %}
{% include "unicode_symbols.rc" %}
{% include "color_glyphs.rc" %}
OPTIONS=!tutorial,!safe_wait,!tips
OPTIONS=showdamage
OPTIONS=cond_held,cond_ice,cond_lava,cond_woundedlegs
OPTIONS=paranoid_confirmation:pray Remove trap swim
BIND=O:optionsfull
{% include "pergame.rc" %}

9
hdf-tnnt.rc Normal file
View File

@@ -0,0 +1,9 @@
{% include "main.rc" %}
{% include "basic_symbols.rc" %}
OPTIONS=cond_held,cond_ice,cond_lava,cond_woundedlegs
OPTIONS=paranoid_confirmation:pray trap A Remove
OPTIONS=realtime:p,realtime_format:f
{% include "pergame.rc" %}

22
justfile Normal file
View File

@@ -0,0 +1,22 @@
[private]
@list:
just --list
[group("show")]
@show_37 *FLAGS:
uv run upload.py hdf-37.rc {{FLAGS}}
[group("show")]
@show_tnnt *FLAGS:
uv run upload.py hdf-tnnt.rc {{FLAGS}}
[group("upload")]
@v37 *FLAGS:
uv run upload.py hdf-37.rc -v nethack {{FLAGS}}
[group("upload")]
@tnnt *FLAGS:
uv run upload.py hdf-tnnt.rc -v tnnt {{FLAGS}}
[group("upload")]
all *FLAGS: (v37 FLAGS) (tnnt FLAGS)

57
main.rc Normal file
View File

@@ -0,0 +1,57 @@
# junethack karafruit
OPTIONS=symset:Enhanced1,roguesymset:plain
OPTIONS=!force_invmenu
OPTIONS=suppress_alert:3.3.1
OPTIONS=map_mode:tiles,scroll_margin:10
OPTIONS=font_message:Consolas,font_size_message:14,align_message:top
OPTIONS=font_menu:Consolas,font_size_menu:14
OPTIONS=font_text:Courier New,font_size_text:14
OPTIONS=font_status:Courier New,font_size_status:14
OPTIONS=hilite_pet,hilite_pile,!toptenwin
#OPTIONS=!splash_screen,player_selection:prompts
AUTOCOMPLETE=twoweapon
{% include "menucolor.rc" %}
{% include "statusbar.rc" %}
{% include "msgtypes.rc" %}
OPTIONS=dogname:Athena
OPTIONS=catname:Moldorm
OPTIONS=horsename:Horse
OPTIONS=fruitname:word
OPTIONS=autopickup,pickup_types:$
autopickup_exception=">.*iron chain.*"
autopickup_exception=">.*heavy iron ball.*"
OPTIONS=scores:10 top/2 around/own
OPTIONS=time,showexp,number_pad:2,lit_corridor
OPTIONS=msg_window:reversed,sortloot:full
OPTIONS=autoquiver
# OPTIONS=invweight,showdmg,showweight
OPTIONS=!cmdassist
OPTIONS=boulder:0,travel
OPTIONS=disclose:yi ya nv ng yc no
OPTIONS=altmeta
OPTIONS=!autodig
OPTIONS=statuslines:3
OPTIONS=pickup_burden=B
OPTIONS=paranoid_confirmation:p t A s
# OPTIONS=realtime:p,realtime_format:f
OPTIONS=runmode:teleport
OPTIONS=quick_farsight
OPTIONS=whatis_coord:c
OPTIONS=!implicit_uncursed
BIND=M-m:terrain
BIND=C:conduct
BIND=!:annotate

83
menucolor.rc Normal file
View File

@@ -0,0 +1,83 @@
OPTIONS=menucolors,menu_objsyms
### Item Status (BUC/worn)
MENUCOLOR=""=white
MENUCOLOR="gold pieces?"=yellow
MENUCOLOR="[Bb]lessed"=green
MENUCOLOR="[Hh]oly"=green
MENUCOLOR="[Cc]ursed"=red
MENUCOLOR="[Uu]nholy"=red
MENUCOLOR="[Uu]ncursed"=gray
MENUCOLOR=".*(being worn|\(wielded|weapon in|lit\)|\(on (left|right)|at the ready|in quiver)"=white&inverse
MENUCOLOR="[Cc]ursed.*(being worn|\(wielded|weapon in|lit\)|\(on (left|right)|at the ready|in quiver)"=red&inverse
MENUCOLOR="[Uu]ncursed.*(being worn|\(wielded|weapon in|lit\)|\(on (left|right)|at the ready|in quiver)"=gray&inverse
MENUCOLOR="[Bb]lessed.*(being worn|\(wielded|weapon in|lit\)|\(on (left|right)|at the ready|in quiver)"=green&inverse
### Items
## Gray Stones
MENUCOLOR="luckstone|called luck"=bright blue
MENUCOLOR="touchstone|called touch"=bright blue
MENUCOLOR=" [Cc]ursed luckstone|[Cc]usred.*called luck"=red
MENUCOLOR="loadstone|called load"=red
MENUCOLOR="gray stone"=red
MENUCOLOR="doppelganger corpse"=red
MENUCOLOR="were.* corpse"=red
## Gemstones
MENUCOLOR="dilithium crystal"=yellow
MENUCOLOR="diamond"=yellow
MENUCOLOR="rub(y|ies)"=yellow
MENUCOLOR="jacinth stone"=yellow
MENUCOLOR="sapphire"=yellow
MENUCOLOR="black opal"=yellow
MENUCOLOR="emerald"=yellow
MENUCOLOR="turquoise stone"=yellow
MENUCOLOR="citrine"=yellow
MENUCOLOR="aquamarine"=yellow
MENUCOLOR="amber stone"=yellow
MENUCOLOR="topaz stone"=yellow
MENUCOLOR="jet stone"=yellow
MENUCOLOR="opals"=yellow
MENUCOLOR="chrysoberyl"=yellow
MENUCOLOR="garnet stone"=yellow
MENUCOLOR="amethyst"=yellow
MENUCOLOR="jasper stone"=yellow
MENUCOLOR="fluorite"=yellow
MENUCOLOR="jade stone"=yellow
MENUCOLOR="obsidian"=yellow
MENUCOLOR="agate stone"=yellow
MENUCOLOR="Amulet of Yendor named"=blue
MENUCOLOR="Amulet of Yendor named.*(being worn|\(wielded|weapon in|lit\)|\(on (left|right)|at the ready|in quiver)"=blue&inverse
MENUCOLOR="wand (of|called) cancellation"=cyan
MENUCOLOR="bag (of|called) tricks"=cyan
## Branches
MENUCOLOR="The Dungeons of Doom:"=bright blue&reverse
MENUCOLOR="The Gnomish Mines:"=bright blue&reverse
MENUCOLOR="Sokoban:"=bright blue&reverse
MENUCOLOR="The Quest:"=bright blue&reverse
MENUCOLOR="Fort Ludios:"=bright blue&reverse
MENUCOLOR="Gehennom:"=bright blue&reverse
MENUCOLOR="Vlad.s Tower:"=bright blue&reverse
MENUCOLOR="The Elemental Planes:"=bright blue&reverse
MENUCOLOR="The Tutorial:"=bright blue&reverse
MENUCOLOR="Portal to The Quest"=bright blue&underline
MENUCOLOR="Portal to Fort Ludios"=bright blue&underline
## |TNNT|
MENUCOLOR="DevTeam Office:"=bright blue&reverse
MENUCOLOR="Deathmatch Arena:"=bright blue&reverse
MENUCOLOR="robotfindskitten:"=bright blue&reverse
## Spells
MENUCOLOR="100%.*%"=red
MENUCOLOR="%.*\(gone\)"=orange
MENUCOLOR="implicit_uncursed"=gray

106
msgtypes.rc Normal file
View File

@@ -0,0 +1,106 @@
MSGTYPE=hide "Unknown command '.*'."
MSGTYPE=hide "You swap places with .*"
MSGTYPE=hide "attack passes harmlessly through the shade"
# MSGTYPE=hide "(It|The .*|.*'s ghost) (misses|touches|bites|hits) (it|the .*|.*'s ghost)"
MSGTYPE=hide "The fire doesn't seem to burn (it|the .*|.*'s ghost)"
MSGTYPE=hide "(It|The .*|.*'s ghost) is mildly warmed"
MSGTYPE=hide "(It|The .*|.*'s ghost) is uninjured"
MSGTYPE=hide "\(I hope you don't mind\.\)"
MSGTYPE=hide "Most likely all your gold was stolen from this"
MSGTYPE=hide "is not affected by oxidation"
MSGTYPE=norep "A mysterious force prevents the .* from teleporting"
MSGTYPE=show "magic missile (hits|misses)"
MSGTYPE=show "spell (hits|misses)"
MSGTYPE=show "wand (hits|misses)"
MSGTYPE=show "dagger (hits|misses)"
MSGTYPE=show "dart (hits|misses)"
MSGTYPE=show "ray (hits|misses)"
MSGTYPE=show "death ray"
MSGTYPE=show "water flow"
## Danger
MSGTYPE=stop "You are slowing down"
MSGTYPE=stop "Your limbs are .*"
MSGTYPE=stop ".* swings itself around you.*"
MSGTYPE=stop "You find it hard to breathe"
MSGTYPE=stop "You are turning a little .*"
MSGTYPE=stop "You feel feverish"
MSGTYPE=stop "steals? |stole"
MSGTYPE=stop "The Wizard of Yendor steals .*"
MSGTYPE=stop "flicks a bullwhip towards your"
MSGTYPE=stop "wraps around the"
MSGTYPE=stop "yanks the"
MSGTYPE=stop "hand spasms"
MSGTYPE=stop "disintegration"
MSGTYPE=stop "wields .*Vorpal Blade"
MSGTYPE=stop "swings .*Vorpal Blade"
MSGTYPE=stop "zaps .* with wand of teleportation"
MSGTYPE=stop "You feel a malgnant aura surround you."
MSGTYPE=stop "(thoroughly|utterly|totally) digest"
MSGTYPE=stop "(feel sad|have a (peculiarly)? (sad|melancholy) feeling) for a moment"
MSGTYPE=stop ".* starves"
MSGTYPE=stop "Run away! Run away!"
MSGTYPE=stop "Watch out! Bad things can happen on Friday the 13th."
## Draining
MSGTYPE=stop "Goodbye level .*." # Default
MSGTYPE=stop "Fare thee well level .*." # Knight
MSGTYPE=stop "Sayonara level .*." # Samurai
MSGTYPE=stop "Aloha level .*." # Tourist
MSGTYPE=stop "Farvel level .*." # Valkyrie
## Good Things
MSGTYPE=stop "You feel a strange mental acuity"
MSGTYPE=stop "You feel (especially)? healthy"
MSGTYPE=stop "You feel hardy"
MSGTYPE=stop "You feel wide awake"
MSGTYPE=stop "You feel a momentary chill"
MSGTYPE=stop "You feel full of hot air"
MSGTYPE=stop "You feel very firm"
MSGTYPE=stop "Your health currently feels amplified"
MSGTYPE=stop "Magic spreads through your body as you digest"
MSGTYPE=stop "You have a feeling of reconciliation"
MSGTYPE=stop "You feel more confident"
MSGTYPE=stop "grows up"
## Vault
MSGTYPE=stop "You (dream that you )?hear the footsteps of a guard on patrol"
MSGTYPE=stop "You (dream that you )?hear someone counting"
## Excalibur
MSGTYPE=stop "From the murky depths, a hand reaches up to bless the sword"
## Amulet of Yendor
MSGTYPE=stop "Amulet of Yendor named"
MSGTYPE=stop "You don't have anything to eat."
MSGTYPE=stop "You cannot eat that"
MSGTYPE=stop "You don't have that object"
MSGTYPE=stop "won't move|still eating"
MSGTYPE=stop "Closed for inventory"
MSGTYPE=stop "You wrest .*"
MSGTYPE=stop "You feel a strange vibration"
## Gremlin stealing your intrinsic at night
MSGTYPE=stop "The gremlin chuckles."
MSGTYPE=stop "You hear laughter."
MSGTYPE=stop "Some writing vanishes from.*head!"
MSGTYPE=stop "You feel warmer."
MSGTYPE=stop "You feel less jumpy."
MSGTYPE=stop "You feel a little sick!"
MSGTYPE=stop "Your senses fail!"
MSGTYPE=stop "You feel cooler."
MSGTYPE=stop "You feel paranoid."
MSGTYPE=stop "You thought you saw something!"
MSGTYPE=stop "You tawt you taw a puttie tat!"
MSGTYPE=stop "You feel slower."
MSGTYPE=stop "You feel clumsy."
MSGTYPE=stop "You feel vulnerable."
MSGTYPE=stop "You feel less attractive."

4
pergame.rc Normal file
View File

@@ -0,0 +1,4 @@
{{ "# " if not nobones }}OPTIONS=nobones
{{ "# " if not nopet }}OPTIONS=nopet
{{ "# " if not pauper }}OPTIONS=pauper
{{ "# " if not nudist }}OPTIONS=nudist

11
pyproject.toml Normal file
View File

@@ -0,0 +1,11 @@
[project]
name = "nethackrc"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
"argparse>=1.4.0",
"jinja2>=3.1.6",
"pyquery>=2.0.1",
"python-dotenv>=1.1.1",
"requests>=2.32.5",
]

52
statusbar.rc Normal file
View File

@@ -0,0 +1,52 @@
OPTIONS=windowcolors:status white/#000000 message white/#000000 text white/#000000 menu white/#000000
OPTIONS=vary_msgcount:4
# Status hilites
OPTIONS=statushilites
## HP
OPTIONS=hitpointbar
OPTIONS=hilite_status:hitpoints/100%/gray&normal
OPTIONS=hilite_status:hitpoints/<100%/green&normal
OPTIONS=hilite_status:hitpoints/<66%/yellow&normal
OPTIONS=hilite_status:hitpoints/<50%/orange&normal
OPTIONS=hilite_status:hitpoints/<33%/red&bold
OPTIONS=hilite_status:hitpoints/<15%/red&inverse
## Pw
OPTIONS=hilite_status:power/100%/gray&normal
OPTIONS=hilite_status:power/<100%/green&normal
OPTIONS=hilite_status:power/<66%/yellow&normal
OPTIONS=hilite_status:power/<50%/orange&normal
OPTIONS=hilite_status:power/<33%/red&bold
## Carry
OPTIONS=hilite_status:cap/burdened/yellow/stressed/orange/strained/red&bold/overtaxed/red&inverse/overloaded/red&inverse&blink
## Hunger
OPTIONS=hilite_status:hunger/satiated/yellow/hungry/orange/weak/red&bold/fainting/red&inverse/fainted/red&inverse&blink
## Mental
OPTIONS=hilite_status:condition/hallu/yellow
OPTIONS=hilite_status:condition/conf/orange
OPTIONS=hilite_status:condition/stun/red&bold
## Health
OPTIONS=hilite_status:condition/termill/red&inverse
OPTIONS=hilite_status:condition/foodpois/red&inverse
OPTIONS=hilite_status:condition/slime/red&inverse
OPTIONS=hilite_status:condition/stone/red&inverse
OPTIONS=hilite_status:condition/strngl/red&inverse
# gold
OPTIONS=hilite_status:gold/up/yellow/down/brown
# St, Dx, Co, In, Wi, Ch
OPTIONS=hilite_status:characteristics/up/green/down/red
# AC
OPTIONS=hilite_status:armor-class/down/green/up/red
# XP
OPTIONS=hilite_status:experience/up/green/down/red
OPTIONS=hilite_status:experience-level/up/green/down/red

19
unicode_symbols.rc Normal file
View File

@@ -0,0 +1,19 @@
SYMBOLS=S_magic_portal:U+058D
SYMBOLS=S_rust_trap:U+2020
SYMBOLS=S_ghost:U+0262
SYMBOLS=S_throne:U+1D8B
SYMBOLS=S_altar:U+03C0
SYMBOLS=S_fountain:U+03D4
SYMBOLS=S_water:U+2248
SYMBOLS=S_pool:U+2248
SYMBOLS=S_lava:U+2248
SYMBOLS=S_sink:U+0534
SYMBOLS=S_sw_ml:U+007C
SYMBOLS=S_sw_mr:U+007C
SYMBOLS=S_sw_tc:U+002D
SYMBOLS=S_sw_bc:U+002D
SYMBOLS=S_explode4:U+007C
SYMBOLS=S_explode6:U+007C
SYMBOLS=S_explode2:U+002D
SYMBOLS=S_explode8:U+002D

53
upload.py Normal file
View File

@@ -0,0 +1,53 @@
import argparse
from dotenv import load_dotenv
from jinja2 import Environment, FileSystemLoader
from pyquery import PyQuery as pq
import os
import requests
import sys
def render(filename, options={}):
env = Environment(loader=FileSystemLoader("."), trim_blocks=True, lstrip_blocks=True)
template = env.get_template(filename)
return template.render(options)
def upload(rcfile, variant):
load_dotenv()
s = requests.Session()
base_url = f"https://www.hardfought.org/nh/{variant}"
s.post(f"{base_url}/login.php", {
"username": os.getenv("HDF_USERNAME"),
"password": os.getenv("HDF_PASSWORD"),
"submit": "Login",
})
get_page = s.get(f"{base_url}/rcedit.php")
csrf_token = pq(get_page.content)('input[name="csrf_token"]').attr("value")
s.post(f"{base_url}/rcedit.php", {
"csrf_token": csrf_token,
"rctext": rcfile,
"submit": "Save+RC+File",
})
print(f"Uploaded variant {variant}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("template")
parser.add_argument("-v", "--variant")
parser.add_argument("--nudist", "-n", action="store_true")
parser.add_argument("--pauper", "-p", action="store_true")
parser.add_argument("--nobones", action="store_true")
parser.add_argument("--nopet", action="store_true")
args = parser.parse_args()
rcfile = render(args.template, vars(args))
if args.variant:
upload(rcfile, args.variant)
else:
print(rcfile)