59 lines
3.2 KiB
Python
59 lines
3.2 KiB
Python
"""Nine tiles form one 48px piston face; vanilla rotations cover all six axes."""
|
|
import json
|
|
from pathlib import Path
|
|
root=Path(__file__).resolve().parents[1]/'mods/sanctuary/src/main/resources/assets/sanctuary'
|
|
models=root/'models/block/super_piston';models.mkdir(parents=True,exist_ok=True)
|
|
rotations={'north':{},'east':{'y':90},'south':{'y':180},'west':{'y':270},'up':{'x':270},'down':{'x':90}}
|
|
textures={n:'sanctuary:block/super_piston/'+n for n in ['bottom','inner','side','top','top_sticky']};textures['particle']=textures['side']
|
|
def write(name,elements):
|
|
(models/(name+'.json')).write_text(json.dumps({'textures':textures,'elements':elements},indent=2)+'\n')
|
|
def face(tex,uv,rotation=0,cull=None):
|
|
f={'texture':'#'+tex,'uv':uv}
|
|
if rotation:f['rotation']=rotation
|
|
if cull:f['cullface']=cull
|
|
return f
|
|
def uv(u,v):return [u*16/3,v*16/3,(u+1)*16/3,(v+1)*16/3]
|
|
def sides(x,y,thin=False,extended=False):
|
|
result={}
|
|
for d,u,r in [('up',x,0),('down',2-x,180),('west',y,270),('east',2-y,90)]:
|
|
result[d]=face('side',[u*16/3,4 if extended else 0,(u+1)*16/3,4 if thin else 16],r,None if thin else d)
|
|
return result
|
|
def shaft(start=0,end=16):
|
|
# Use only the central 16px wood tile of the 48px plate, at native pixel
|
|
# density. Short base/head segments sample only their actual length.
|
|
faces={}
|
|
for d in rotations:
|
|
pixels=([2,2,14,14] if d in ('north','south') else
|
|
[2,start,14,end] if d in ('up','down') else [start,2,end,14])
|
|
faces[d]=face('top',[(16+p)/3 for p in pixels])
|
|
return {'from':[2,2,start],'to':[14,14,end],'faces':faces}
|
|
for part in range(9):
|
|
x,y=part%3,part//3
|
|
for front in ['top','top_sticky','inner']:
|
|
extended=front=='inner'
|
|
faces=sides(x,y,extended=extended);faces['north']=face(front,uv(2-x,2-y),cull=None if extended else 'north');faces['south']=face('bottom',uv(x,2-y),cull='south')
|
|
pieces=[{'from':[0,0,4 if extended else 0],'to':[16,16,16],'faces':faces}]
|
|
if extended and part==4:
|
|
pieces.append(shaft(0,4))
|
|
write(f'base_{front}_{part}',pieces)
|
|
for sticky in [False,True]:
|
|
faces=sides(x,y,True);faces['north']=face('top_sticky' if sticky else 'top',uv(2-x,2-y));faces['south']=face('top',uv(x,2-y))
|
|
pieces=[{'from':[0,0,0],'to':[16,16,4],'faces':faces}]
|
|
if part==4:
|
|
pieces.append(shaft(4,16))
|
|
write(f'head_{str(sticky).lower()}_{part}',pieces)
|
|
write('rod',[shaft()])
|
|
(root/'blockstates').mkdir(parents=True,exist_ok=True)
|
|
for name in ['super_piston','super_sticky_piston','super_piston_head','super_piston_rod']:
|
|
variants={}
|
|
for facing,rotation in rotations.items():
|
|
if name.endswith('_rod'):variants[f'facing={facing}']={'model':'sanctuary:block/super_piston/rod',**rotation};continue
|
|
for part in range(9):
|
|
if name.endswith('_head'):
|
|
for sticky in [False,True]:variants[f'facing={facing},part={part},sticky={str(sticky).lower()}']={'model':f'sanctuary:block/super_piston/head_{str(sticky).lower()}_{part}',**rotation}
|
|
else:
|
|
for extended in [False,True]:
|
|
front='inner' if extended else 'top_sticky' if 'sticky' in name else 'top'
|
|
variants[f'extended={str(extended).lower()},facing={facing},part={part}']={'model':f'sanctuary:block/super_piston/base_{front}_{part}',**rotation}
|
|
(root/'blockstates'/(name+'.json')).write_text(json.dumps({'variants':variants},indent=2)+'\n')
|