Compare commits

...

4 commits

Author SHA1 Message Date
e4c5c8b475 Skip the warp flag when generating the dsda text file.
This causes negative tics to work, for whatever reason.
2025-08-01 02:09:15 -04:00
70e1a3a39e PEP 8 compliance. 2025-08-01 02:07:06 -04:00
1ee4ea4dc6 Universally use double quotes for strings. 2025-08-01 02:05:05 -04:00
7925281ceb Add "run it back" command to continue a practice run after failing a demo. 2025-08-01 02:03:30 -04:00
6 changed files with 88 additions and 42 deletions

View file

@ -11,8 +11,8 @@ class Base(Command):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super().get_parser(prog_name) parser = super().get_parser(prog_name)
parser.add_argument( parser.add_argument(
'--doom', default=pathlib.Path.home().joinpath("doom")) "--doom", default=pathlib.Path.home().joinpath("doom"))
parser.add_argument('--config-name', default='config.toml') parser.add_argument("--config-name", default="config.toml")
return parser return parser
def init_base(self, parsed_args): def init_base(self, parsed_args):

View file

@ -10,7 +10,7 @@ import tomlkit
class Wad(dcc.config.Base): class Wad(dcc.config.Base):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super().get_parser(prog_name) parser = super().get_parser(prog_name)
parser.add_argument('wad') parser.add_argument("wad")
return parser return parser
def wad_init(self, parsed_args): def wad_init(self, parsed_args):
@ -53,7 +53,7 @@ class Wad(dcc.config.Base):
def load_order(self): def load_order(self):
wads = self._config.get("load_order") wads = self._config.get("load_order")
if wads is None: if wads is None:
wads = sorted(self.pwad_path.glob('*.wad', case_sensitive=False)) wads = sorted(self.pwad_path.glob("*.wad", case_sensitive=False))
else: else:
wads = [self.pwad_path.joinpath(wad) for wad in wads] wads = [self.pwad_path.joinpath(wad) for wad in wads]
return wads return wads
@ -73,8 +73,8 @@ class Wad(dcc.config.Base):
class WadMap(Wad): class WadMap(Wad):
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super().get_parser(prog_name) parser = super().get_parser(prog_name)
parser.add_argument('map') parser.add_argument("map")
parser.add_argument('-n', '--name', '--demo_name') parser.add_argument("-n", "--name", "--demo_name")
return parser return parser
def run(self, parsed_args): def run(self, parsed_args):
@ -92,20 +92,21 @@ class WadMap(Wad):
def name_string(self): def name_string(self):
return "" if self._name is None else "_" + self._name return "" if self._name is None else "_" + self._name
def dsda_preamble(self): def dsda_preamble(self, warp=True):
args = ["-iwad", self.iwad_path] args = ["-iwad", self.iwad_path]
wads = self.load_order() wads = self.load_order()
if len(wads) > 0: if len(wads) > 0:
args = args + ["-file"] + wads args = args + ["-file"] + wads
dehs = sorted(self.pwad_path.glob('*.deh', case_sensitive=False)) dehs = sorted(self.pwad_path.glob("*.deh", case_sensitive=False))
if len(dehs) > 0: if len(dehs) > 0:
args = args + ["-deh"] + dehs args = args + ["-deh"] + dehs
args = args + ["-complevel", str(self.complevel())] args = args + ["-complevel", str(self.complevel())]
args = args + ["-skill", "4"] args = args + ["-skill", "4"]
args = args + ["-warp", self.map] if warp:
args = args + ["-warp", self.map]
args = args + self.options() args = args + self.options()
return args return args

View file

@ -21,12 +21,10 @@ class DSDA(dcc.doom_base.WadMap):
command = [self.dsda] command = [self.dsda]
if shutil.which("xvfb-run") is not None: if shutil.which("xvfb-run") is not None:
command = ["xvfb-run"] + command command = ["xvfb-run"] + command
# TODO: negative tics should seek from the end, but this doesn't
# seem to work.
subprocess.run( subprocess.run(
command + self.dsda_preamble() + [ command + self.dsda_preamble(warp=False) + [
"-fastdemo", dip, "-nosound", "-skiptic", "-fastdemo", dip, "-nosound",
"999999999", "-export_text_file" "-skiptic", "-1", "-export_text_file"
] ]
) )
editor = "nano" editor = "nano"

View file

@ -59,6 +59,8 @@ class Fetch(dcc.config.Base):
if fetcher_path is None: if fetcher_path is None:
raise Exception(f"Fetch util {fetcher} not found on PATH.") raise Exception(f"Fetch util {fetcher} not found on PATH.")
proc = subprocess.run([fetcher_path, url], capture_output=True, check = True) proc = subprocess.run(
[fetcher_path, url],
capture_output=True, check=True
)
return json.loads(proc.stdout) return json.loads(proc.stdout)

44
dcc/rib.py Normal file
View file

@ -0,0 +1,44 @@
import dcc.doom_base
import pathlib
import os
import subprocess
import time
class RIB(dcc.doom_base.WadMap):
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
parser.add_argument("-s", "--secs_before", default=10)
return parser
# TODO: the root path should probably be configurable.
def take_action(self, parsed_args):
demo = ""
dt = 0
demodir = (
pathlib.Path.home() /
".dsda-doom" /
"dsda_doom_data" /
self.iwad_path.stem.lower()
)
for w in self.load_order():
demodir = demodir.joinpath(w.stem.lower())
demodir = demodir / "failed_demos"
for f in demodir.glob(f"*map{self.map}*", case_sensitive=False):
st = os.stat(f)
if st.st_mtime > dt:
demo = f
dt = st.st_mtime
if demo == "":
raise Exception(
f"no failed demos found for wad {parsed_args.wad} "
+ f"and map {parsed_args.map} (tried to look in {demodir})"
)
subprocess.run(
[self.dsda] + self.dsda_preamble(warp=False)
+ ["-playdemo", demo]
+ ["-skiptic", str(-35 * parsed_args.secs_before)]
)

View file

@ -1,41 +1,42 @@
from setuptools import find_packages from setuptools import find_packages
from setuptools import setup from setuptools import setup
PROJECT = 'dcc' PROJECT = "dcc"
VERSION = '0.0.1' VERSION = "0.0.1"
long_description = '' long_description = ""
setup( setup(
name=PROJECT, name=PROJECT,
version=VERSION, version=VERSION,
description='Doom Command Center', description="Doom Command Center",
long_description=long_description, long_description=long_description,
author='yrriban', author="yrriban",
author_email='yrriban@gmail.com', author_email="yrriban@gmail.com",
platforms=['Any'], platforms=["Any"],
install_requires=['cliff'], install_requires=["cliff"],
packages=find_packages(), packages=find_packages(),
include_package_data=True, include_package_data=True,
entry_points={ entry_points={
'console_scripts': ['dcc=dcc.main:main'], "console_scripts": ["dcc=dcc.main:main"],
'dcc': [ "dcc": [
'play = dcc.play:Play', "play = dcc.play:Play",
'record = dcc.record:Record', "record = dcc.record:Record",
'fabricate = dcc.fabricate:Fabricate', "rib = dcc.rib:RIB",
'put = dcc.put:Put', "fabricate = dcc.fabricate:Fabricate",
'pb = dcc.pb:PB', "put = dcc.put:Put",
'ss = dcc.ss:SS', "pb = dcc.pb:PB",
'extract = dcc.extract:Extract', "ss = dcc.ss:SS",
'fetch = dcc.fetch:Fetch', "extract = dcc.extract:Extract",
'text = dcc.text:Text', "fetch = dcc.fetch:Fetch",
'thumb = dcc.thumb:Thumb', "text = dcc.text:Text",
'dsda = dcc.dsda:DSDA', "thumb = dcc.thumb:Thumb",
'eureka = dcc.eureka:Eureka', "dsda = dcc.dsda:DSDA",
'ls = dcc.ls:List', "eureka = dcc.eureka:Eureka",
'configure = dcc.configure:Configure', "ls = dcc.ls:List",
'concat = dcc.concat:Concat', "configure = dcc.configure:Configure",
"concat = dcc.concat:Concat",
], ],
}, },
zip_safe=False, zip_safe=False,