saumwacht-godot/assets-source/phase4/blender/catalog.py
Martin Stickelbroeck c2b447610c Baseline: Saumwacht 0.15.0 (Phase 20A) vor dem Umbau zu Champions of Luneraria
Unveränderter Ausgangsstand inklusive Masterprompt und Konzeptbildern
unter assets/. .godot/ und docs/screenshots/ bleiben laut .gitignore
unversioniert; letztere sind unter ../backups gesichert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:00:36 +02:00

62 lines
3.3 KiB
Python

"""Art parameters only; combat statistics remain in Godot's DataCatalog.
Edit HEIGHTS, FOOTPRINT or individual specs to change proportions. Upgraded
models switch geometry in their builder; they are never only enlarged copies.
"""
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parent
PROJECT = ROOT.parents[2]
SOURCE = ROOT.parent
DEFAULT_EXPORT_DIR = PROJECT / 'assets' / 'models'
DEFAULT_BLEND_DIR = SOURCE / 'blend'
FOOTPRINT = 1.85 # Fits inside a 2m construction cell, including weapons.
HEIGHTS = {'melee': 1.35, 'tank': 1.35, 'ranged': 1.45, 'artillery': 1.35, 'support': 1.45}
def specs():
plan = json.loads((PROJECT / 'assets-source/phase3/asset_plan.json').read_text())['assets']
result = []
for asset in plan:
if asset['kind'] not in ('unit_icon', 'mercenary_icon'):
continue
number = int(asset['id'][1:])
if asset['kind'] == 'unit_icon':
roles = ['melee', 'tank', 'ranged', 'artillery', 'support']
if asset['faction'] in ('nietenkonvent', 'nebelchor'):
roles[0], roles[1] = roles[1], roles[0]
role = roles[(number - 1) // 2]
upgraded = number % 2 == 0
height = HEIGHTS[role] + (0.15 if upgraded else 0)
else:
role, upgraded, height = 'mercenary', False, 1.4 + (0.15 if number == 5 else 0)
result.append({'id': asset['id'], 'name': asset['display_name'],
'faction': asset['faction'], 'palette': asset['faction'],
'role': role, 'upgraded': upgraded, 'height': height,
'footprint': FOOTPRINT, 'file': 'unit_' + asset['id'] + '.glb'})
result.extend([
{'id': 'worker', 'name': 'Funkenleser', 'faction': 'neutral', 'palette': 'worker',
'role': 'worker', 'upgraded': False, 'height': 1.1, 'footprint': 1.4, 'file': 'worker.glb'},
{'id': 'map_lane_segment', 'name': 'Lane-Segment', 'faction': 'terrain', 'palette': 'terrain',
'role': 'lane', 'upgraded': False, 'height': 0, 'file': 'map_lane_segment.glb'},
*[{'id': 'core_team' + str(team), 'name': 'Saumkern · Team ' + str(team),
'faction': 'team' + str(team), 'palette': 'team' + str(team), 'role': 'core',
'team': team, 'upgraded': False, 'height': 2.2, 'footprint': 3.2,
'file': 'core_team' + str(team) + '.glb'} for team in (0, 1)]
])
enemies=[('e01','Splitterling',1.05,1.85),('e02','Schalenläufer',1.42,1.85),('e03','Nebelrest',1.9,1.55),('e04','Fadenschütze',1.8,1.85),('e05','Bruchstampfer',2.0,2.1),('e06','Knotenrufer',2.0,1.9),('e07','Bruchhirsch',2.6,2.5),('e08','Riegelkoloss',2.6,2.7),('e09','Maskenrichter',2.9,2.6),('e10','Schlundkrone',2.9,3.1)]
for id,name,height,footprint in enemies:
result.append({'id':id,'name':name,'faction':'rift','palette':'neutral','role':'enemy','upgraded':False,'height':height,'footprint':footprint,'file':'enemy_'+id+'.glb'})
for spec in result:
if spec['faction'] in ('glutpakt','wurzelbund','rift','neutral') or spec['role'] in ('lane','core'):
spec['triangle_budget'] = 180000
spec['detail_level'] = 'high'
return result
def get_spec(asset_id):
for spec in specs():
if spec['id'] == asset_id:
return dict(spec)
raise ValueError('Unknown asset ID: ' + asset_id)