initial commit
This commit is contained in:
commit
c2bb3893a9
1038 changed files with 75846 additions and 0 deletions
50
tools/fix_stale_tres_paths.py
Normal file
50
tools/fix_stale_tres_paths.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Fix stale res://textures/td_sliced/<UPPER>.png references in .tres files
|
||||
under textures/tb/ — rewrites them to the new tb/<role>/<family>/<variant>.png
|
||||
location. Cosmetic only; Godot already resolves these via UID."""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
TB_ROOT = Path.home() / "godot_projects/trench/textures/tb"
|
||||
|
||||
ROLE_MAP = {
|
||||
"brick": "wall", "concrete": "wall", "stucco": "wall", "steel": "wall",
|
||||
"wood": "wall", "panel": "wall", "tech": "wall", "lab": "wall",
|
||||
"rivet": "wall", "tile": "wall", "hedge": "wall", "fence": "wall",
|
||||
"floor": "floor", "cobbles": "floor", "dirt": "floor", "grass": "floor",
|
||||
"sand": "floor", "tarmac": "floor", "sidewalk": "floor", "grid": "floor",
|
||||
"door": "door", "bigdoor": "door", "ldoor": "door", "rdoor": "door",
|
||||
"doortrim": "trim", "ledge": "trim", "step": "trim", "support": "trim",
|
||||
"pipes": "trim", "vent": "trim",
|
||||
"light": "light",
|
||||
"blood": "decal", "warn": "decal", "paper": "decal",
|
||||
"slime": "liquid", "sludge": "liquid",
|
||||
"crate": "prop", "console": "prop", "switch": "prop",
|
||||
}
|
||||
|
||||
basename_re = re.compile(r"^([a-z]+)_(\d+[a-z](?:_[a-z]+)?)\.png$")
|
||||
ref_re = re.compile(r'res://textures/td_sliced/([^"]+\.png)')
|
||||
|
||||
fixed = 0
|
||||
|
||||
for tres in TB_ROOT.rglob("*.tres"):
|
||||
text = tres.read_text()
|
||||
|
||||
def replace(m):
|
||||
old = m.group(1).lower()
|
||||
bm = basename_re.match(old)
|
||||
if not bm:
|
||||
return m.group(0)
|
||||
family, variant = bm.group(1), bm.group(2)
|
||||
role = ROLE_MAP.get(family)
|
||||
if not role:
|
||||
return m.group(0)
|
||||
return f"res://textures/tb/{role}/{family}/{variant}.png"
|
||||
|
||||
new_text = ref_re.sub(replace, text)
|
||||
if new_text != text:
|
||||
tres.write_text(new_text)
|
||||
fixed += 1
|
||||
|
||||
print(f"Fixed {fixed} .tres files")
|
||||
47
tools/lowercase_textures.py
Normal file
47
tools/lowercase_textures.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Lowercase every file in textures/td_sliced/ and fix the source_file= field
|
||||
inside .png.import files so Godot can still find the source PNG."""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
SRC = Path.home() / "godot_projects/trench/textures/td_sliced"
|
||||
|
||||
renamed = 0
|
||||
skipped = 0
|
||||
collisions = []
|
||||
|
||||
# Snapshot before mutating
|
||||
files = sorted(SRC.iterdir())
|
||||
|
||||
for f in files:
|
||||
if not f.is_file():
|
||||
continue
|
||||
lower = f.name.lower()
|
||||
if lower == f.name:
|
||||
skipped += 1
|
||||
continue
|
||||
target = f.parent / lower
|
||||
if target.exists():
|
||||
collisions.append(f.name)
|
||||
continue
|
||||
f.rename(target)
|
||||
renamed += 1
|
||||
|
||||
# Fix source_file= inside every .png.import in the folder
|
||||
for imp in sorted(SRC.glob("*.png.import")):
|
||||
text = imp.read_text()
|
||||
new_text = re.sub(
|
||||
r'(source_file="res://textures/td_sliced/)([^"]+)"',
|
||||
lambda m: f'{m.group(1)}{m.group(2).lower()}"',
|
||||
text,
|
||||
)
|
||||
if new_text != text:
|
||||
imp.write_text(new_text)
|
||||
|
||||
print(f"renamed: {renamed}")
|
||||
print(f"already-lowercase: {skipped}")
|
||||
if collisions:
|
||||
print(f"COLLISIONS (target already existed): {len(collisions)}")
|
||||
for c in collisions:
|
||||
print(f" {c}")
|
||||
81
tools/reorganize_textures.py
Normal file
81
tools/reorganize_textures.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Reorganize textures/td_sliced/ into textures/tb/<family>/<variant>.png
|
||||
|
||||
Already-lowercase precondition: run lowercase_textures.py first.
|
||||
|
||||
For each <family>_<variant>.png in the source folder, moves:
|
||||
- the .png itself
|
||||
- the .png.import sibling (with source_file= rewritten)
|
||||
- the .tres sibling (if any) with its path= field rewritten
|
||||
|
||||
Files that don't match the family_variant pattern are left in place.
|
||||
"""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path.home() / "godot_projects/trench/textures"
|
||||
SRC = ROOT / "td_sliced"
|
||||
DST_BASE = ROOT / "tb"
|
||||
|
||||
# family_variant.png OR family_variant_tag.png
|
||||
# variant must start with a digit (so we don't accidentally split a multi-word
|
||||
# family name on its first underscore)
|
||||
NAME_RE = re.compile(r"^([a-z]+)_(\d+[a-z](?:_[a-z]+)?)\.png$")
|
||||
|
||||
moved_groups = 0
|
||||
moved_files = 0
|
||||
skipped = []
|
||||
|
||||
png_files = sorted(SRC.glob("*.png"))
|
||||
|
||||
for png in png_files:
|
||||
m = NAME_RE.match(png.name)
|
||||
if not m:
|
||||
skipped.append(png.name)
|
||||
continue
|
||||
|
||||
family, variant = m.group(1), m.group(2)
|
||||
new_dir = DST_BASE / family
|
||||
new_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
new_png = new_dir / f"{variant}.png"
|
||||
new_imp = new_dir / f"{variant}.png.import"
|
||||
new_tres = new_dir / f"{variant}.tres"
|
||||
|
||||
if new_png.exists():
|
||||
print(f"COLLISION skip: {png.name} -> {new_png}")
|
||||
continue
|
||||
|
||||
# Move .png
|
||||
png.rename(new_png)
|
||||
|
||||
# Move + rewrite .png.import
|
||||
old_imp = png.with_suffix(".png.import")
|
||||
if old_imp.exists():
|
||||
text = old_imp.read_text()
|
||||
text = text.replace(
|
||||
f"res://textures/td_sliced/{png.name}",
|
||||
f"res://textures/tb/{family}/{variant}.png",
|
||||
)
|
||||
old_imp.unlink()
|
||||
new_imp.write_text(text)
|
||||
|
||||
# Move + rewrite sibling .tres material if it exists
|
||||
old_tres = png.with_suffix(".tres")
|
||||
if old_tres.exists():
|
||||
text = old_tres.read_text()
|
||||
text = text.replace(
|
||||
f"res://textures/td_sliced/{png.name}",
|
||||
f"res://textures/tb/{family}/{variant}.png",
|
||||
)
|
||||
old_tres.unlink()
|
||||
new_tres.write_text(text)
|
||||
|
||||
moved_groups += 1
|
||||
moved_files += 1 + int(old_imp.exists() is False) * 0 # always counted via group
|
||||
|
||||
print(f"\nmoved {moved_groups} groups")
|
||||
print(f"skipped (non-matching) {len(skipped)} files:")
|
||||
for s in skipped:
|
||||
print(f" {s}")
|
||||
84
tools/role_reorg.py
Normal file
84
tools/role_reorg.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Move textures/tb/<family>/ into textures/tb/<role>/<family>/ and rewrite path refs.
|
||||
|
||||
Run with Godot editor closed. Operates in place. Reversible by reading the
|
||||
final report and inverting the mapping.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path.home() / "godot_projects/trench/textures/tb"
|
||||
|
||||
ROLE_MAP = {
|
||||
# walls
|
||||
"brick": "wall", "concrete": "wall", "stucco": "wall", "steel": "wall",
|
||||
"wood": "wall", "panel": "wall", "tech": "wall", "lab": "wall",
|
||||
"rivet": "wall", "tile": "wall", "hedge": "wall", "fence": "wall",
|
||||
# floors
|
||||
"floor": "floor", "cobbles": "floor", "dirt": "floor", "grass": "floor",
|
||||
"sand": "floor", "tarmac": "floor", "sidewalk": "floor", "grid": "floor",
|
||||
# doors
|
||||
"door": "door", "bigdoor": "door", "ldoor": "door", "rdoor": "door",
|
||||
# trim
|
||||
"doortrim": "trim", "ledge": "trim", "step": "trim", "support": "trim",
|
||||
"pipes": "trim", "vent": "trim",
|
||||
# light
|
||||
"light": "light",
|
||||
# decal / liquid / prop
|
||||
"blood": "decal", "warn": "decal", "paper": "decal",
|
||||
"slime": "liquid", "sludge": "liquid",
|
||||
"crate": "prop", "console": "prop", "switch": "prop",
|
||||
}
|
||||
|
||||
ROLES = set(ROLE_MAP.values())
|
||||
|
||||
# Step 1: families whose name matches a role (floor, door, light) need a temp
|
||||
# rename so they don't collide with the role folder we're about to create.
|
||||
conflicts = {fam for fam in ROLE_MAP if fam in ROLES}
|
||||
for fam in conflicts:
|
||||
src = ROOT / fam
|
||||
if src.is_dir():
|
||||
src.rename(ROOT / f"__tmp_{fam}")
|
||||
|
||||
# Step 2: move each family into its role folder, rewriting path refs.
|
||||
moved = 0
|
||||
updated = 0
|
||||
|
||||
for fam, role in ROLE_MAP.items():
|
||||
src = ROOT / (f"__tmp_{fam}" if fam in conflicts else fam)
|
||||
if not src.is_dir():
|
||||
continue
|
||||
|
||||
role_dir = ROOT / role
|
||||
role_dir.mkdir(exist_ok=True)
|
||||
|
||||
dst = role_dir / fam
|
||||
if dst.exists():
|
||||
print(f"COLLISION: {dst} already exists, skipping {fam}")
|
||||
continue
|
||||
|
||||
src.rename(dst)
|
||||
moved += 1
|
||||
|
||||
old_prefix = f"res://textures/tb/{fam}/"
|
||||
new_prefix = f"res://textures/tb/{role}/{fam}/"
|
||||
for f in dst.iterdir():
|
||||
if not f.is_file():
|
||||
continue
|
||||
if f.name.endswith(".png.import") or f.suffix == ".tres":
|
||||
text = f.read_text()
|
||||
new_text = text.replace(old_prefix, new_prefix)
|
||||
if new_text != text:
|
||||
f.write_text(new_text)
|
||||
updated += 1
|
||||
|
||||
# Check for unknown families left at the top level
|
||||
unknown = [
|
||||
d.name for d in ROOT.iterdir()
|
||||
if d.is_dir() and d.name not in ROLES and not d.name.startswith("__tmp_")
|
||||
]
|
||||
|
||||
print(f"\nMoved {moved} families into {len(ROLES)} role folders")
|
||||
print(f"Updated {updated} ref files (.png.import + .tres)")
|
||||
if unknown:
|
||||
print(f"\nWARNING: unknown families left at top level: {unknown}")
|
||||
Loading…
Add table
Add a link
Reference in a new issue