This commit is contained in:
2025-05-25 23:37:40 +03:00
commit 7f054e2904
79 changed files with 4850 additions and 0 deletions

112
tools/mapcc.py Normal file
View File

@@ -0,0 +1,112 @@
import sys
import struct
import os
import re
def parse_map(file_path):
with open(file_path, 'r') as f:
lines = f.readlines()
entities = []
stack = []
current_entity = None
current_brush = None
face_pattern = re.compile(r"""
(?:\(\s*(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*\)\s*)
(?:\(\s*(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*\)\s*)
(?:\(\s*(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*\)\s*)
(?:\(\s*(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*\)\s*)
(?:\(\s*(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*\)\s*)
(?:\(\s*(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*\)\s*)
(\S+)
""", re.VERBOSE)
for line in lines:
line = line.strip()
if not line or line.startswith('//'):
continue
if line == '{':
stack.append('{')
if current_entity is None:
current_entity = {'classname': None, 'keyvalues': {}, 'brushes': []}
elif current_brush is None:
current_brush = []
continue
if line == '}':
if current_brush is not None:
current_entity['brushes'] = current_brush
current_brush = None
else:
entities.append(current_entity)
current_entity = None
stack.pop()
continue
if current_brush is not None:
m = face_pattern.match(line)
if m:
points = [
(float(m.group(1)), float(m.group(2)), float(m.group(3))),
(float(m.group(4)), float(m.group(5)), float(m.group(6))),
(float(m.group(7)), float(m.group(8)), float(m.group(9))),
]
uvs = [
(float(m.group(10)), float(m.group(11))),
(float(m.group(12)), float(m.group(13))),
(float(m.group(14)), float(m.group(15))),
]
texture = m.group(16)
face = {
'points': points,
'uvs': uvs,
'texture': texture,
}
current_brush.append(face)
else:
print(f"Warning: Could not parse face line: {line}")
continue
if current_entity is not None:
if line.startswith('"'):
parts = re.findall(r'"([^"]*)"', line)
if len(parts) == 2:
key, value = parts
if key == "classname":
current_entity['classname'] = value
else:
current_entity['keyvalues'][key] = value
else:
print(f"Warning: Unexpected line in entity: {line}")
return entities
if (len(sys.argv)==1):
print("mapcc.py is a rtt's .map to .fmap converter");
print("key changes:");
print("- uses triangles instead of brushes");
print("- uses uv coordinates instead of brushes");
print("use better map editor instead of this");
exit(0)
entities = parse_map(sys.argv[1])
pakfilename = sys.argv[2]
pakfile = open(pakfilename,"wb")
pakfile.write(struct.Struct("<8sI").pack(b"rttfmapc",len(entities)))
for i, e in enumerate(entities):
pakfile.write(struct.Struct(f"<{len(e['classname'])+1}s").pack(str(e['classname']).encode("ascii")))
pakfile.write(struct.Struct("<I").pack(len(e['brushes'])))
pakfile.write(struct.Struct("<I").pack(len(e['keyvalues'])))
for k, v in e['keyvalues'].items():
pakfile.write(struct.Struct(f"<{len(k)+1}s").pack(k.encode("ascii")))
pakfile.write(struct.Struct(f"<{len(v)+1}s").pack(v.encode("ascii")))
for k, face in enumerate(e['brushes']):
# the fuck
for i in range(9):
pakfile.write(struct.Struct(f"<f").pack(float(face['points'][int(i/3)][i%3])))
for i in range(6):
pakfile.write(struct.Struct(f"<f").pack(float(face['uvs'][int(i//2)][i%2])))
pakfile.write(struct.Struct(f"<{len(face['texture'])+1}s").pack(face['texture'].encode("ascii")))