initial commit: llamamod 0.2.0 – reverse-engineered level formats (wad, map, trak, text, stpc), python tools and notes, java mod manager (iso install, mod pipeline with exe patching, save editor, wine/windows launcher) with mods (test world, debug wireframe, mirror, randomizer, fog, cheats, intro skip, practice, free camera, boot to level, level projects) and the 3d level editor (geometry, objects, cross-world import, environment, textures, play-test, manual)

This commit is contained in:
MineTec committed 2026-11-07 08:15:40 +01:00
commit b36a366240
826 files changed
+105304

No files matched your search

+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""Liest und schreibt Level-WADs von "Ein Königreich für ein Lama" (Argonaut).
Aufbau: u32 Gesamtlänge (ohne dieses Feld), dann Chunks:
4 Byte Kennung (rückwärts gespeichert, z. B. 'OFNI' = INFO), u32 Länge, Daten
bis zum Chunk 'END '.
wadtool.py list level.wad
wadtool.py name level.wad neu.wad "Neuer Levelname"
wadtool.py extract level.wad CHUNK datei.bin
wadtool.py replace level.wad neu.wad CHUNK datei.bin
"""
import struct
import sys
def read(path):
d = open(path, 'rb').read()
total = struct.unpack_from('<I', d, 0)[0]
if total != len(d) - 4:
raise ValueError(f'{path}: Längenfeld {total} passt nicht zu {len(d) - 4}')
chunks, o = [], 4
while o + 8 <= len(d):
tag = d[o:o + 4][::-1].decode('latin1')
ln = struct.unpack_from('<I', d, o + 4)[0]
chunks.append([tag, d[o + 8:o + 8 + ln]])
o += 8 + ln
if tag == 'END ':
break
return chunks
def write(path, chunks):
body = b''.join(t.encode('latin1')[::-1] + struct.pack('<I', len(c)) + c for t, c in chunks)
open(path, 'wb').write(struct.pack('<I', len(body)) + body)
def get(chunks, tag):
for c in chunks:
if c[0] == tag:
return c
raise KeyError(tag)
if __name__ == '__main__':
cmd, src = sys.argv[1], sys.argv[2]
ch = read(src)
if cmd == 'list':
for t, c in ch:
extra = ''
if t == 'NAME':
extra = repr(c[4:].split(b'\0')[0].decode('latin1'))
print(f'{t!r:8} {len(c):10d} {extra}')
elif cmd == 'name':
c = get(ch, 'NAME')
c[1] = c[1][:4] + sys.argv[4].encode('latin1') + b'\0'
write(sys.argv[3], ch)
elif cmd == 'extract':
open(sys.argv[4], 'wb').write(get(ch, sys.argv[3].ljust(4))[1])
elif cmd == 'replace':
get(ch, sys.argv[4].ljust(4))[1] = open(sys.argv[5], 'rb').read()
write(sys.argv[3], ch)
else:
sys.exit(__doc__)