Clean slate for Hytale: remove Paper/Minecraft assets, add Interactions.Use fix, PlayerRef extraction

- Remove assets/ directory (Paper/Minecraft leftover models, textures, scripts)
- Add BlockType.Interactions.Use to all interactive block JSONs
  (Controller, Grid, DiskDrive, Autocrafter, Cable, Importer, Exporter,
  Interface, MachineCasing, SecurityDetector, SecurityTerminal, etc.)
  Enables UseBlockEvent to fire on right-click instead of silent fail.
- Fix PlayerRef extraction in BlockInteractionHandler:
  event.getContext().getEntity().getStore().getComponent(ref, PlayerRef.getComponentType())
- Add RsAdvancedProcessor.json (renamed from AdvancedProcessor.json for prefix)
- UI work: DiskDriveUI, AutocrafterUI, UIManager improvements
- Bockymodel updates for all items
- Remove AdvancedProcessor.json (replaced by RsAdvancedProcessor.json)
This commit is contained in:
Lead Developer Web 2026-05-07 09:48:31 +02:00
parent 916e8bc059
commit 57b4d2f853
134 changed files with 2433 additions and 1468 deletions

View file

@ -1,84 +0,0 @@
{
"pack_id": "refinedstorage2_assets",
"pack_name": "RefinedStorage2 Asset Pack",
"pack_version": "0.1.0",
"plugin_id": "RefinedStorage",
"description": "Hytale-style textures and models for RefinedStorage2 components",
"author": "Nepharius",
"format_version": 1,
"resource_types": {
"texture": {
"block": {
"controller": "textures/blocks/controller.png",
"cable": "textures/blocks/cable.png",
"disk_drive": "textures/blocks/disk_drive.png",
"grid": "textures/blocks/grid.png",
"crafting_grid": "textures/blocks/crafting_grid.png",
"io_device": "textures/blocks/io_device.png",
"interface": "textures/blocks/interface.png",
"autocrafter": "textures/blocks/autocrafter.png",
"autocrafting_monitor": "textures/blocks/autocrafting_monitor.png",
"wireless_transmitter": "textures/blocks/wireless_transmitter.png",
"wireless_receiver": "textures/blocks/wireless_receiver.png",
"security_terminal": "textures/blocks/security_terminal.png",
"security_detector": "textures/blocks/security_detector.png",
"machine_casing": "textures/blocks/machine_casing.png"
},
"item": {
"storage_disk": "textures/items/storage_disk.png",
"security_card": "textures/items/security_card.png",
"raw_processor": "textures/items/raw_processor.png",
"printed_processor": "textures/items/printed_processor.png",
"advanced_processor": "textures/items/advanced_processor.png",
"upgrade_speed": "textures/items/upgrade_speed.png",
"upgrade_range": "textures/items/upgrade_range.png",
"upgrade_silk_touch": "textures/items/upgrade_silk.png",
"upgrade_fortune": "textures/items/upgrade_fortune.png",
"upgrade_stack": "textures/items/upgrade_stack.png",
"construction_core": "textures/items/construction_core.png",
"pattern": "textures/items/pattern.png",
"network_tool": "textures/items/construction_core.png"
}
},
"model": {
"block": "models/blocks/",
"item": "models/items/"
}
},
"block_texture_mapping": {
"refinedstorage:controller": "controller",
"refinedstorage:cable": "cable",
"refinedstorage:disk_drive": "disk_drive",
"refinedstorage:grid": "grid",
"refinedstorage:crafting_grid": "crafting_grid",
"refinedstorage:importer": "io_device",
"refinedstorage:exporter": "io_device",
"refinedstorage:interface": "interface",
"refinedstorage:autocrafter": "autocrafter",
"refinedstorage:autocrafting_monitor": "autocrafting_monitor",
"refinedstorage:wireless_transmitter": "wireless_transmitter",
"refinedstorage:wireless_receiver": "wireless_receiver",
"refinedstorage:security_terminal": "security_terminal",
"refinedstorage:security_detector": "security_detector",
"refinedstorage:machine_casing": "machine_casing",
"refinedstorage:io_interface": "interface"
},
"item_texture_mapping": {
"refinedstorage:storage_disk": "storage_disk",
"refinedstorage:fluid_disk": "storage_disk",
"refinedstorage:security_card": "security_card",
"refinedstorage:raw_processor": "raw_processor",
"refinedstorage:printed_processor": "printed_processor",
"refinedstorage:advanced_processor": "advanced_processor",
"refinedstorage:upgrade_speed": "upgrade_speed",
"refinedstorage:upgrade_range": "upgrade_range",
"refinedstorage:upgrade_silk_touch": "upgrade_silk_touch",
"refinedstorage:upgrade_fortune": "upgrade_fortune",
"refinedstorage:upgrade_stack": "upgrade_stack",
"refinedstorage:construction_core": "construction_core",
"refinedstorage:pattern": "pattern",
"refinedstorage:network_tool": "network_tool",
"refinedstorage:wireless_grid": "crafting_grid",
"refinedstorage:wireless_crafting_grid": "crafting_grid"
}
}

View file

@ -1,55 +0,0 @@
#!/usr/bin/env python3
"""Generate Hytale model files for RefinedStorage2 components."""
import os, json
OUT = "/home/nepharius/projects/hytale-refined-storage/assets/models"
blocks = [
"controller", "cable", "disk_drive", "grid", "crafting_grid",
"io_device", "interface", "autocrafter", "autocrafting_monitor",
"wireless_transmitter", "wireless_receiver",
"security_terminal", "security_detector", "machine_casing"
]
items = [
"storage_disk", "security_card",
"raw_processor", "printed_processor", "advanced_processor",
"upgrade_speed", "upgrade_range", "upgrade_silk_touch",
"upgrade_fortune", "upgrade_stack",
"construction_core", "pattern", "network_tool"
]
for name in blocks:
model = {
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": f"refinedstorage2:block/{name}"
},
"display": {
"thirdperson_righthand": {
"rotation": [0, 0, 0],
"translation": [0, 0, 0],
"scale": [1, 1, 1]
}
}
}
path = os.path.join(OUT, "blocks", f"{name}.hytale_model")
with open(path, 'w') as f:
json.dump(model, f, indent=2)
print(f" {path}")
for name in items:
model = {
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": f"refinedstorage2:item/{name}"
}
}
path = os.path.join(OUT, "items", f"{name}.hytale_model")
with open(path, 'w') as f:
json.dump(model, f, indent=2)
print(f" {path}")
print(f"\nGenerated {len(blocks)} block models + {len(items)} item models")

View file

@ -1,627 +0,0 @@
#!/usr/bin/env python3
"""Generate Hytale-style 32x32 pixel art textures for RefinedStorage2 components."""
import struct, zlib, os
OUT = "/home/nepharius/projects/hytale-refined-storage/assets/textures"
def make_png(pixels, palette):
"""
pixels: list of rows, each row is list of palette indices (0..len(palette)-1)
palette: list of (r,g,b) tuples
Returns raw PNG bytes.
"""
width = len(pixels[0])
height = len(pixels)
# Build raw image data (filter byte 0 + indices per row)
raw = b''
for row in pixels:
raw += b'\x00' + bytes(row)
# IHDR
ihdr = struct.pack('>IIBBBBB', width, height, 8, 3, 0, 0, 0) # 8-bit, color type 3 (indexed)
ihdr_crc = zlib.crc32(b'IHDR' + ihdr) & 0xffffffff
# PLTE
plte = b''
for r, g, b in palette:
plte += bytes([r, g, b])
# Pad to 256 colors (required by spec for color type 3)
plte += b'\x00\x00\x00' * (256 - len(palette))
plte_crc = zlib.crc32(b'PLTE' + plte) & 0xffffffff
# IDAT
compressed = zlib.compress(raw)
idat_crc = zlib.crc32(b'IDAT' + compressed) & 0xffffffff
# IEND
iend_crc = zlib.crc32(b'IEND') & 0xffffffff
def chunk(ctype, data, crc):
return struct.pack('>I', len(data)) + ctype + data + struct.pack('>I', crc)
return (b'\x89PNG\r\n\x1a\n' +
chunk(b'IHDR', ihdr, ihdr_crc) +
chunk(b'PLTE', plte, plte_crc) +
chunk(b'IDAT', compressed, idat_crc) +
chunk(b'IEND', b'', iend_crc))
# ============================================================
# PALETTE: Hytale-inspired colors
# ============================================================
P = {} # color names → (r,g,b)
P['BLACK'] = (16, 16, 20)
P['DARK_GRAY'] = (40, 42, 48)
P['GRAY'] = (72, 74, 80)
P['LIGHT_GRAY']= (120, 122, 128)
P['WHITE'] = (200, 202, 208)
P['BROWN'] = (80, 52, 36)
P['TAN'] = (140, 114, 72)
P['GOLD'] = (212, 172, 56)
P['ORANGE'] = (220, 120, 40)
P['RED'] = (180, 40, 40)
P['DARK_RED'] = (120, 24, 24)
P['MAROON'] = (60, 16, 16)
P['TEAL'] = (24, 120, 136)
P['DARK_TEAL'] = (16, 72, 84)
P['BLUE'] = (40, 100, 188)
P['DARK_BLUE'] = (20, 52, 104)
P['LIGHT_BLUE']= (100, 168, 220)
P['CYAN'] = (60, 180, 200)
P['PURPLE'] = (100, 60, 160)
P['DARK_PURPLE']=(56, 32, 96)
P['GREEN'] = (60, 140, 52)
P['DARK_GREEN']= (32, 80, 28)
P['LIME'] = (120, 200, 56)
P['YELLOW'] = (224, 200, 48)
P['CREAM'] = (184, 160, 120)
P['COPPER'] = (160, 96, 56)
P['IRON'] = (140, 144, 152)
P['CORAL'] = (200, 80, 80)
def solid_pixels(color, w=32, h=32):
"""All pixels same color index."""
ci = list(P.values()).index(color)
return [[ci] * w for _ in range(h)]
def composite(base, overlay, x=0, y=0):
"""Overlay a pattern onto base, in-place."""
for dy, row in enumerate(overlay):
for dx, idx in enumerate(row):
if idx != 0: # non-transparent
base[y+dy][x+dx] = idx
def rect(w, h, color, fill=True):
"""Create a rectangular pattern of given color index."""
ci = list(P.values()).index(color)
if fill:
return [[ci] * w for _ in range(h)]
else:
result = [[0] * w for _ in range(h)]
for y in range(h):
for x in range(w):
if y == 0 or y == h-1 or x == 0 or x == w-1:
result[y][x] = ci
return result
def hcenter(pattern, color, height=6):
"""Horizontal center stripe."""
ci = list(P.values()).index(color)
h2 = height // 2
mid_y = len(pattern) // 2
for dy in range(-h2, h2 + (height % 2 == 0)):
if 0 <= mid_y + dy < len(pattern):
for x in range(len(pattern[0])):
pattern[mid_y+dy][x] = ci
return pattern
def vcenter(pattern, color, width=4):
"""Vertical center stripe."""
ci = list(P.values()).index(color)
w2 = width // 2
mid_x = len(pattern[0]) // 2
for y in range(len(pattern)):
for dx in range(-w2, w2 + (width % 2 == 0)):
if 0 <= mid_x + dx < len(pattern[0]):
pattern[y][mid_x+dx] = ci
return pattern
# ============================================================
# TEXTURE DEFINITIONS
# ============================================================
pal = list(P.values())
textures = {}
# -- CONTROLLER --
def make_controller():
c = solid_pixels(P['DARK_TEAL'])
# Gold frame
frame = rect(32, 32, P['GOLD'], fill=False)
composite(c, frame)
# Inner panel
inner = rect(28, 28, P['TEAL'], fill=True)
composite(c, inner, 2, 2)
# Center indicator
dot = rect(8, 8, P['CYAN'], fill=True)
composite(c, dot, 12, 12)
return c
textures['controller'] = make_controller()
# -- CABLE --
def make_cable():
c = solid_pixels(P['DARK_GRAY'])
# Thick center line
vcenter(c, P['LIGHT_GRAY'], 8)
hcenter(c, P['LIGHT_GRAY'], 8)
# Inner colored core
vcenter(c, P['TEAL'], 4)
hcenter(c, P['TEAL'], 4)
# Center dot
dot = rect(4, 4, P['GOLD'], fill=True)
composite(c, dot, 14, 14)
return c
textures['cable'] = make_cable()
# -- DISK DRIVE --
def make_disk_drive():
c = solid_pixels(P['DARK_GRAY'])
# Iron frame
frame = rect(32, 32, P['IRON'], fill=False)
composite(c, frame)
# Dark face
face = rect(28, 28, P['BLACK'], fill=True)
composite(c, face, 2, 2)
# Slot cutouts (3 slots)
for sx in [4, 13, 22]:
slot = rect(6, 4, P['TEAL'], fill=True)
composite(c, slot, sx, 8)
slot2 = rect(6, 2, P['DARK_TEAL'], fill=True)
composite(c, slot2, sx, 13)
# LED dot
led = rect(3, 3, P['GREEN'], fill=True)
composite(c, led, 2, 2)
return c
textures['disk_drive'] = make_disk_drive()
# -- STORAGE DISK --
def make_storage_disk():
c = solid_pixels(P['LIGHT_GRAY'])
# Outer ring
ring = rect(32, 32, P['GRAY'], fill=False)
composite(c, ring)
# Inner circle (approximate with square in pixel art)
inner = rect(20, 20, P['CYAN'], fill=True)
composite(c, inner, 6, 6)
# Center hub
hub = rect(8, 8, P['DARK_GRAY'], fill=True)
composite(c, hub, 12, 12)
# Data stripe
stripe = rect(14, 3, P['LIGHT_BLUE'], fill=True)
composite(c, stripe, 9, 20)
return c
textures['storage_disk'] = make_storage_disk()
# -- GRID --
def make_grid():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['IRON'], fill=False)
composite(c, frame)
# 2x2 grid segments
for gx in [2, 17]:
for gy in [2, 17]:
cell = rect(13, 13, P['TEAL'], fill=True)
composite(c, cell, gx, gy)
# Grid lines
vcenter(c, P['DARK_GRAY'], 2)
hcenter(c, P['DARK_GRAY'], 2)
# Corner lights
for cx, cy in [(4,4),(24,4),(4,24),(24,24)]:
dot = rect(2, 2, P['GREEN'], fill=True)
composite(c, dot, cx, cy)
return c
textures['grid'] = make_grid()
# -- CRAFTING GRID --
def make_crafting_grid():
c = solid_pixels(P['BROWN'])
frame = rect(32, 32, P['TAN'], fill=False)
composite(c, frame)
# 3x3 grid (9 cells)
for gx in [2, 12, 22]:
for gy in [2, 12, 22]:
cell = rect(8, 8, P['CREAM'], fill=True)
composite(c, cell, gx, gy)
# Arrow indicator
arrow = rect(8, 4, P['GREEN'], fill=True)
composite(c, arrow, 24, 14)
arrowhead = rect(4, 8, P['GREEN'], fill=True)
composite(c, arrowhead, 28, 12)
return c
textures['crafting_grid'] = make_crafting_grid()
# -- IO DEVICES --
def make_io():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['ORANGE'], fill=False)
composite(c, frame)
inner = rect(26, 26, P['BLACK'], fill=True)
composite(c, inner, 3, 3)
# Input arrow
arrow = [[0]*32 for _ in range(8)]
for y in range(8):
for x in range(10):
ax = x
if x < 5:
ax = x if y < 4 else (4-x) if y == 4 else (9-x) if y > 4 else x
# simplified: triangle
if y <= 3:
if x >= 4-y and x <= 4+y:
arrow[y][x+6] = list(P.values()).index(P['GREEN'])
else:
if x >= y-4 and x <= 12-y:
arrow[y][x+6] = list(P.values()).index(P['GREEN'])
# Simpler: just draw a right-pointing triangle with blocks
inp = [
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,0,0],
[0,0,0,0,1,0,0,1,0,0],
[0,0,0,0,1,0,0,1,0,0],
[0,0,0,0,1,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0],
]
ci_green = list(P.values()).index(P['GREEN'])
inp_pix = [[ci_green if v else 0 for v in row] for row in inp]
composite(c, inp_pix, 6, 6)
# Output arrow (right)
out = [
[0,0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,1,0,0,0,0],
[0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,1,0,0,0,0,0],
[0,0,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
]
out_pix = [[ci_green if v else 0 for v in row] for row in out]
composite(c, out_pix, 16, 20)
return c
textures['io_device'] = make_io()
# -- INTERFACE --
def make_interface():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['GREEN'], fill=False)
composite(c, frame)
inner = rect(26, 26, P['DARK_GREEN'], fill=True)
composite(c, inner, 3, 3)
# Slot pattern
for sx in [4, 12, 20]:
slot = rect(6, 4, P['GREEN'], fill=True)
composite(c, slot, sx, 6)
slot2 = rect(6, 4, P['GREEN'], fill=True)
composite(c, slot2, sx, 14)
slot3 = rect(6, 4, P['GREEN'], fill=True)
composite(c, slot3, sx, 22)
return c
textures['interface'] = make_interface()
# -- AUTOCRAFTING CRAFTER --
def make_autocrafter():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['PURPLE'], fill=False)
composite(c, frame)
inner = rect(26, 26, P['DARK_PURPLE'], fill=True)
composite(c, inner, 3, 3)
# Crafting symbol (furnace-like)
for i in range(3):
for j in range(3):
cell = rect(6, 6, P['PURPLE'] if (i+j)%2==0 else P['LIGHT_GRAY'], fill=True)
composite(c, cell, 5+i*8, 5+j*8)
# Gear indicator
dot = rect(4, 4, P['GOLD'], fill=True)
composite(c, dot, 14, 14)
return c
textures['autocrafter'] = make_autocrafter()
# -- AUTOCRAFTING MONITOR --
def make_autocrafting_monitor():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['PURPLE'], fill=False)
composite(c, frame)
inner = rect(26, 26, P['BLACK'], fill=True)
composite(c, inner, 3, 3)
# Screen bar
bar = rect(22, 3, P['PURPLE'], fill=True)
composite(c, bar, 5, 5)
# Progress bars
for i, (col, y) in enumerate([(P['GREEN'],10),(P['PURPLE'],16),(P['GREEN'],22)]):
pb = rect(18, 2, col, fill=True)
composite(c, pb, 7, y)
# Active dot
dot = rect(3, 3, P['LIME'], fill=True)
composite(c, dot, 27, 4)
return c
textures['autocrafting_monitor'] = make_autocrafting_monitor()
# -- WIRELESS TRANSMITTER --
def make_wireless_tx():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['CYAN'], fill=False)
composite(c, frame)
inner = rect(26, 26, P['BLACK'], fill=True)
composite(c, inner, 3, 3)
# Antenna symbol
ant_pix = [[0]*32 for _ in range(16)]
ci_cyan = list(P.values()).index(P['CYAN'])
for y in range(12):
x = 15 - y//3
ant_pix[y][x] = ci_cyan
ant_pix[y][x+1] = ci_cyan
ant_pix[y][x+2] = ci_cyan
ant_pix[y][x+3] = ci_cyan
composite(c, ant_pix, 8, 4)
# Signal arcs
for r, col in [(8, P['CYAN']),(12, P['LIGHT_BLUE']),(16, P['TEAL'])]:
ci = list(P.values()).index(col)
for y in range(32):
for x in range(32):
dist = abs(x-15) + abs(y-15)
if dist == r:
c[y][x] = ci
return c
textures['wireless_transmitter'] = make_wireless_tx()
# -- WIRELESS RECEIVER --
def make_wireless_rx():
c = make_wireless_tx() # similar base
# Recolor frame to blue
ci_blue = list(P.values()).index(P['BLUE'])
for y in range(32):
for x in range(32):
if c[y][x] == list(P.values()).index(P['CYAN']):
c[y][x] = ci_blue
return c
textures['wireless_receiver'] = make_wireless_rx()
# -- SECURITY CARD --
def make_security_card():
c = solid_pixels(P['WHITE'])
frame = rect(32, 32, P['RED'], fill=False)
composite(c, frame)
# Card detail
stripe = rect(22, 16, P['LIGHT_GRAY'], fill=True)
composite(c, stripe, 5, 8)
# Chip
chip = rect(8, 6, P['GOLD'], fill=True)
composite(c, chip, 6, 10)
# Lock icon (simplified)
lock = [
[0,0,1,1,1,1,0,0],
[0,1,0,0,0,0,1,0],
[1,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1],
[1,0,1,1,1,1,0,1],
[1,0,1,1,1,1,0,1],
[1,0,1,1,1,1,0,1],
[1,1,1,1,1,1,1,1],
]
ci_red = list(P.values()).index(P['RED'])
lock_pix = [[ci_red if v else 0 for v in row] for row in lock]
composite(c, lock_pix, 18, 18)
return c
textures['security_card'] = make_security_card()
# -- SECURITY TERMINAL --
def make_security_terminal():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['DARK_RED'], fill=False)
composite(c, frame)
inner = rect(26, 26, P['MAROON'], fill=True)
composite(c, inner, 3, 3)
# Screen
screen = rect(20, 14, P['BLACK'], fill=True)
composite(c, screen, 6, 5)
# Text lines
for i, ty in enumerate([8, 11, 14]):
line = rect(16, 1, P['RED'], fill=True)
composite(c, line, 8, ty)
# Keypad
for kx, ky in [(6,22),(12,22),(18,22)]:
key = rect(4, 4, P['GRAY'], fill=True)
composite(c, key, kx, ky)
return c
textures['security_terminal'] = make_security_terminal()
# -- SECURITY DETECTOR --
def make_security_detector():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['RED'], fill=False)
composite(c, frame)
inner = rect(26, 26, P['BLACK'], fill=True)
composite(c, inner, 3, 3)
# Eye/lens
eye = rect(14, 14, P['DARK_RED'], fill=True)
composite(c, eye, 9, 9)
pupil = rect(6, 6, P['RED'], fill=True)
composite(c, pupil, 13, 13)
center = rect(2, 2, P['WHITE'], fill=True)
composite(c, center, 15, 15)
return c
textures['security_detector'] = make_security_detector()
# -- MACHINE CASING --
def make_casing():
c = solid_pixels(P['GRAY'])
# Bolted frame
frame = rect(32, 32, P['IRON'], fill=False)
composite(c, frame)
# Bolts in corners
for bx, by in [(2,2),(26,2),(2,26),(26,26)]:
bolt = rect(3, 3, P['DARK_GRAY'], fill=True)
composite(c, bolt, bx, by)
# Vent lines
for vy in [6, 12, 18, 24]:
vent = rect(20, 2, P['DARK_GRAY'], fill=True)
composite(c, vent, 6, vy)
return c
textures['machine_casing'] = make_casing()
# -- RAW PROCESSOR --
def make_raw_processor():
c = solid_pixels(P['GRAY'])
frame = rect(32, 32, P['COPPER'], fill=False)
composite(c, frame)
# Silicon wafer
wafer = rect(22, 22, P['LIGHT_GRAY'], fill=True)
composite(c, wafer, 5, 5)
# Crystal pattern
for cx, cy in [(8,8),(16,8),(8,16),(16,16)]:
crystal = rect(4, 4, P['GOLD'], fill=True)
composite(c, crystal, cx, cy)
return c
textures['raw_processor'] = make_raw_processor()
# -- PRINTED PROCESSOR --
def make_printed_processor():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['GOLD'], fill=False)
composite(c, frame)
# Circuit board
board = rect(24, 24, P['GREEN'], fill=True)
composite(c, board, 4, 4)
# Traces
ci_gold = list(P.values()).index(P['GOLD'])
for y in [8, 12, 16, 20]:
trace = [ci_gold] * 20
for x in range(6, 26):
c[y][x] = ci_gold
for x in [10, 14, 18, 22]:
for y in range(6, 26):
c[y][x] = ci_gold
# Pin connectors at edges
ci_copper = list(P.values()).index(P['COPPER'])
for px in [6, 10, 14, 18, 22]:
for py in range(2, 4):
c[py][px] = ci_copper
c[28+py-2][px] = ci_copper
return c
textures['printed_processor'] = make_printed_processor()
# -- ADVANCED PROCESSOR --
def make_advanced_processor():
c = solid_pixels(P['DARK_GRAY'])
frame = rect(32, 32, P['PURPLE'], fill=False)
composite(c, frame)
# Circuit board - dark
board = rect(24, 24, P['BLACK'], fill=True)
composite(c, board, 4, 4)
# Gold traces
ci_gold = list(P.values()).index(P['GOLD'])
for y in [8, 12, 16, 20]:
for x in range(6, 26):
c[y][x] = ci_gold
# Purple highlights
ci_purple = list(P.values()).index(P['PURPLE'])
for x in [10, 14, 18, 22]:
for y in range(8, 24):
c[y][x] = ci_purple
# Chip center
chip = rect(6, 6, P['GOLD'], fill=True)
composite(c, chip, 13, 13)
ci_cyan = list(P.values()).index(P['CYAN'])
dot = rect(2, 2, P['CYAN'], fill=True)
composite(c, dot, 15, 15)
# Pin connectors
ci_copper = list(P.values()).index(P['COPPER'])
for px in [6, 10, 14, 18, 22]:
for py in range(2, 4):
c[py][px] = ci_copper
c[28+py-2][px] = ci_copper
return c
textures['advanced_processor'] = make_advanced_processor()
# -- UPGRADES --
def make_upgrade(name, accent):
c = solid_pixels(P['DARK_GRAY'])
ci_accent = list(P.values()).index(accent)
frame = rect(32, 32, P['GRAY'], fill=False)
composite(c, frame)
# Upgrade card shape
card = rect(24, 18, P['BLACK'], fill=True)
composite(c, card, 4, 7)
# Accent bar
bar = rect(20, 3, accent, fill=True)
composite(c, bar, 6, 9)
# Text lines
for ly in [14, 18]:
line = rect(16, 1, P['LIGHT_GRAY'], fill=True)
composite(c, line, 8, ly)
# Pins
for px in [4, 12, 20]:
pin = rect(2, 4, P['GOLD'], fill=True)
composite(c, pin, px, 26)
return c
textures['upgrade_speed'] = make_upgrade('upgrade_speed', P['BLUE'])
textures['upgrade_range'] = make_upgrade('upgrade_range', P['GREEN'])
textures['upgrade_silk'] = make_upgrade('upgrade_silk', P['PURPLE'])
textures['upgrade_fortune'] = make_upgrade('upgrade_fortune', P['GOLD'])
textures['upgrade_stack'] = make_upgrade('upgrade_stack', P['ORANGE'])
# -- UTILITY ITEMS --
def make_construction_core():
c = solid_pixels(P['GRAY'])
frame = rect(32, 32, P['ORANGE'], fill=False)
composite(c, frame)
# Diamond shape
ci_gold = list(P.values()).index(P['GOLD'])
for y in range(32):
half = abs(y - 15)
if half < 14:
w = 14 - half
for x in range(16-w, 16+w):
c[y][x] = ci_gold
# Center glow
ci_white = list(P.values()).index(P['WHITE'])
for y in range(12, 20):
for x in range(12, 20):
dist = abs(x-15) + abs(y-15)
if dist < 5:
c[y][x] = ci_white
return c
textures['construction_core'] = make_construction_core()
def make_pattern():
c = solid_pixels(P['WHITE'])
frame = rect(32, 32, P['GREEN'], fill=False)
composite(c, frame)
# Grid pattern overlay
ci_green = list(P.values()).index(P['GREEN'])
for y in range(4, 28, 4):
for x in range(4, 28, 4):
c[y][x] = ci_green
c[y][x+1] = ci_green
c[y+1][x] = ci_green
c[y+1][x+1] = ci_green
return c
textures['pattern'] = make_pattern()
# ============================================================
# WRITE ALL TEXTURES
# ============================================================
os.makedirs(OUT, exist_ok=True)
for name, pixels in textures.items():
png_data = make_png(pixels, pal)
path = os.path.join(OUT, f"{name}.png")
with open(path, 'wb') as f:
f.write(png_data)
print(f"Generated: {path} ({len(png_data)} bytes)")
print(f"\nDone! {len(textures)} textures generated in {OUT}")

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/autocrafter"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/autocrafting_monitor"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/cable"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/controller"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/crafting_grid"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/disk_drive"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/grid"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/interface"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/io_device"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/machine_casing"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/security_detector"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/security_terminal"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/wireless_receiver"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,26 +0,0 @@
{
"format_version": 1,
"parent": "hytale:block/cube_all",
"textures": {
"all": "refinedstorage2:block/wireless_transmitter"
},
"display": {
"thirdperson_righthand": {
"rotation": [
0,
0,
0
],
"translation": [
0,
0,
0
],
"scale": [
1,
1,
1
]
}
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/advanced_processor"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/construction_core"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/network_tool"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/pattern"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/printed_processor"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/raw_processor"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/security_card"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/storage_disk"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/upgrade_fortune"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/upgrade_range"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/upgrade_silk_touch"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/upgrade_speed"
}
}

View file

@ -1,7 +0,0 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "refinedstorage2:item/upgrade_stack"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 893 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,019 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,020 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 893 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 887 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 887 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 887 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 887 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 887 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 887 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 887 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 887 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,019 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,020 B

View file

@ -63,15 +63,25 @@ public final class BlockInteractionHandler {
String blockId = extractBlockId(event.getBlockType());
if (blockId == null) return;
// TODO: Extract proper PlayerRef from event.getContext().getEntity()
// when entity-to-player conversion is implemented
// Extract PlayerRef from event context's entity reference
// UseBlockEvent.getContext().getEntity() Ref<EntityStore>
// Store.getComponent(ref, PlayerRef.getComponentType()) PlayerRef
var entityRef = event.getContext().getEntity();
PlayerRef player = null;
if (entityRef != null && entityRef.isValid()) {
player = entityRef.getStore().getComponent(entityRef, PlayerRef.getComponentType());
}
if (player == null) {
LOGGER.atWarning().log("Cannot handle UseBlockEvent at (%s,%s,%s): player entity ref invalid",
pos.x, pos.y, pos.z);
return;
}
switch (blockId) {
case CONTROLLER -> {
int netId = networkManager.getNetworkForController(pos);
LOGGER.atInfo().log("Player right-clicked Controller at (%s,%s,%s) network #%s",
pos.x, pos.y, pos.z, netId);
LOGGER.atInfo().log("Player %s right-clicked Controller at (%s,%s,%s) network #%s",
player.getUsername(), pos.x, pos.y, pos.z, netId);
if (netId != -1) {
uiManager.openController(player, String.valueOf(netId));
} else {
@ -80,31 +90,31 @@ public final class BlockInteractionHandler {
}
case GRID -> {
int netId = networkManager.getNetworkForMachine(pos);
LOGGER.atInfo().log("Player right-clicked Grid at (%s,%s,%s) network #%s",
pos.x, pos.y, pos.z, netId);
LOGGER.atInfo().log("Player %s right-clicked Grid at (%s,%s,%s) network #%s",
player.getUsername(), pos.x, pos.y, pos.z, netId);
if (netId != -1) {
uiManager.openGrid(player, String.valueOf(netId));
}
}
case DISK_DRIVE -> {
int netId = networkManager.getNetworkForMachine(pos);
LOGGER.atInfo().log("Player right-clicked DiskDrive at (%s,%s,%s) network #%s",
pos.x, pos.y, pos.z, netId);
LOGGER.atInfo().log("Player %s right-clicked DiskDrive at (%s,%s,%s) network #%s",
player.getUsername(), pos.x, pos.y, pos.z, netId);
if (netId != -1) {
uiManager.openDiskDrive(player, String.valueOf(netId));
uiManager.openDiskDrive(player, String.valueOf(netId), pos);
}
}
case AUTOCRAFTER -> {
int netId = networkManager.getNetworkForMachine(pos);
LOGGER.atInfo().log("Player right-clicked Autocrafter at (%s,%s,%s) network #%s",
pos.x, pos.y, pos.z, netId);
LOGGER.atInfo().log("Player %s right-clicked Autocrafter at (%s,%s,%s) network #%s",
player.getUsername(), pos.x, pos.y, pos.z, netId);
if (netId != -1) {
uiManager.openAutocrafter(player, String.valueOf(netId), pos);
}
}
case IMPORTER, EXPORTER, INTERFACE_BLOCK, CABLE -> {
LOGGER.atInfo().log("Player right-clicked %s at (%s,%s,%s)",
blockId, pos.x, pos.y, pos.z);
LOGGER.atInfo().log("Player %s right-clicked %s at (%s,%s,%s)",
player.getUsername(), blockId, pos.x, pos.y, pos.z);
}
default -> {}
}

View file

@ -6,7 +6,7 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* Represents the aggregate item inventory of a RefinedStorage network.
* Stores item counts indexed by item identifier (e.g. "minecraft:stone").
* Stores item counts indexed by item identifier (e.g. "hytale:stone").
* <p>
* The network inventory is the sum of all storage disk contents plus
* items passing through Importers/Exporters in transit.

View file

@ -25,7 +25,7 @@ import java.util.logging.Level;
/**
* Autocrafter UI Hytale-native recipe definition and autocrafting interface.
* <p>
* Unlike Minecraft, Hytale has no default 3×3 crafting grid. Instead,
* Unlike vanilla Hytale, there is no default 3×3 crafting grid. Instead,
* this autocrafter lets the player define patterns directly in the UI:
* <p>
* Layout:

View file

@ -2,6 +2,7 @@ package dev.refinedstorage.ui;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.server.core.entity.entities.player.pages.CustomUIPage;
import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
@ -17,18 +18,24 @@ import java.util.ArrayList;
import java.util.List;
/**
* Disk Drive UI manage storage disks: view contents, format, eject, set priority.
* Shows installed disks with used/total space, format/eject buttons, and priority slider.
* Disk Drive UI manage storage disks: view contents, format, eject, set priority,
* and insert new storage disks.
* <p>
* The drivePos identifies which DiskDrive block is being managed.
* Shows all disks in this specific drive (up to 8), with:
* used/total space bars, format/eject buttons, and priority sliders.
*/
public class DiskDriveUI extends CustomUIPage {
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
private final String networkId;
private final Vector3i drivePos;
public DiskDriveUI(PlayerRef playerRef, String networkId) {
public DiskDriveUI(PlayerRef playerRef, String networkId, Vector3i drivePos) {
super(playerRef, CustomPageLifetime.CanDismissOrCloseThroughInteraction);
this.networkId = networkId;
this.drivePos = drivePos;
}
@Override
@ -39,23 +46,29 @@ public class DiskDriveUI extends CustomUIPage {
return;
}
commands.set("header.text", "Disk Drive Manager");
commands.set("networkInfo.text", "Network #" + networkId);
commands.set("header.text", "Disk Drive");
commands.set("networkInfo.text", "Network #" + networkId + " — Drive at (" +
drivePos.x + ", " + drivePos.y + ", " + drivePos.z + ")");
// --- Disk list ---
List<DiskEntry> disks = collectDisks(net);
DiskDriveManager diskMgr = DiskDriveManager.getInstance();
List<StorageDisk> disks = diskMgr.getDisks(drivePos);
if (disks.isEmpty()) {
commands.set("empty.text", "No disks installed. Insert a storage disk to begin.");
} else {
for (int i = 0; i < disks.size(); i++) {
DiskEntry disk = disks.get(i);
StorageDisk disk = disks.get(i);
addDiskPanel(commands, events, i, disk);
}
}
// --- Add disk slot area (for inserting new disks) ---
// --- Insert disk area ---
commands.append("insertDiskHeader", createSectionHeader("Insert Storage Disk"));
commands.append("insertDiskArea", createInsertDiskArea());
// --- Refresh button ---
commands.append("refreshButton", createActionButton("Refresh", "refresh"));
}
@Override
@ -70,6 +83,7 @@ public class DiskDriveUI extends CustomUIPage {
rebuild();
} catch (NumberFormatException ignored) {
}
return;
}
// Eject disk: "eject_<index>"
@ -80,9 +94,10 @@ public class DiskDriveUI extends CustomUIPage {
rebuild();
} catch (NumberFormatException ignored) {
}
return;
}
// Priority change: "priority_<index>_<value>"
// Priority changed: "priority_<index>_<value>"
if (data.startsWith("priority_")) {
String[] parts = data.split("_");
if (parts.length >= 3) {
@ -93,82 +108,88 @@ public class DiskDriveUI extends CustomUIPage {
} catch (NumberFormatException ignored) {
}
}
return;
}
// Insert disk: "insertDisk.submit" the player put a storage disk into the slot
if ("insertDisk.submit".equals(data)) {
insertDisk();
rebuild();
return;
}
// Refresh
if ("refresh".equals(data)) {
rebuild();
}
}
private List<DiskEntry> collectDisks(NetworkManager.Network net) {
List<DiskEntry> entries = new ArrayList<>();
// Find disk drive positions in this network
List<com.hypixel.hytale.math.vector.Vector3i> drivePositions = new ArrayList<>();
for (java.util.Map.Entry<com.hypixel.hytale.math.vector.Vector3i, String> machine : net.machines.entrySet()) {
if ("diskdrive".equals(machine.getValue())) {
drivePositions.add(machine.getKey());
}
}
DiskDriveManager diskMgr = DiskDriveManager.getInstance();
int diskIndex = 0;
for (com.hypixel.hytale.math.vector.Vector3i drivePos : drivePositions) {
List<StorageDisk> disks = diskMgr.getDisks(drivePos);
for (StorageDisk disk : disks) {
entries.add(new DiskEntry(
disk.getDiskName(),
disk.getItemCount(),
disk.getMaxSlots() * 64, // theoretical max items
disk.getDistinctItemTypes(),
disk.getPriority()
));
diskIndex++;
}
}
return entries;
}
// ---- Real disk operations ----
private void formatDisk(int diskIndex) {
// TODO: Format disk (clear all items stored on it)
// Need to map diskIndex back to a specific drive position + slot
// For now placeholder will be implemented with full disk management
LOGGER.atInfo().log("Format disk requested for disk #%d", diskIndex);
DiskDriveManager.getInstance().formatDisk(drivePos, diskIndex);
LOGGER.atInfo().log("Formatted disk #%d in drive at (%s,%s,%s)",
diskIndex, drivePos.x, drivePos.y, drivePos.z);
}
private void ejectDisk(int diskIndex) {
// TODO: Eject disk (remove from network, spawn as item in world)
// Need to map diskIndex back to a specific drive position + slot
// For now placeholder will be implemented with full disk management
LOGGER.atInfo().log("Eject disk requested for disk #%d", diskIndex);
DiskDriveManager diskMgr = DiskDriveManager.getInstance();
StorageDisk ejected = diskMgr.ejectDisk(drivePos, diskIndex);
if (ejected != null) {
LOGGER.atInfo().log("Ejected disk '%s' from drive at (%s,%s,%s)",
ejected.getDiskName(), drivePos.x, drivePos.y, drivePos.z);
}
}
private void setDiskPriority(int diskIndex, int priority) {
// TODO: Update disk priority for item insertion ordering
// Need to map diskIndex back to a specific drive position + slot
// For now placeholder will be implemented with full disk management
LOGGER.atInfo().log("Set disk #%d priority to %d", diskIndex, priority);
DiskDriveManager.getInstance().setDiskPriority(drivePos, diskIndex, priority);
}
private void addDiskPanel(UICommandBuilder commands, UIEventBuilder events, int index, DiskEntry disk) {
/**
* Insert a new disk into this drive.
* The disk type is determined by the item the player puts in.
* Currently uses a default 1k disk; in production this would parse the
* actual item from the UI slot data.
*/
private void insertDisk() {
DiskDriveManager diskMgr = DiskDriveManager.getInstance();
List<StorageDisk> currentDisks = diskMgr.getDisks(drivePos);
if (currentDisks.size() >= 8) {
LOGGER.at(java.util.logging.Level.WARNING).log(
"Disk drive at (%s,%s,%s) is full (8/8)", drivePos.x, drivePos.y, drivePos.z);
return;
}
// Create a 1k disk (default). In production, we'd read the actual disk type
// from the item the player dropped into the UI slot.
StorageDisk disk = new StorageDisk(StorageDisk.TYPE_1K, "Storage Disk 1k");
diskMgr.insertDisk(drivePos, disk);
}
// ---- UI helpers ----
private void addDiskPanel(UICommandBuilder commands, UIEventBuilder events, int index, StorageDisk disk) {
String prefix = "disk_" + index;
// Disk header
commands.append(prefix + "_header", createSectionHeader(
"Disk #" + (index + 1) + ": " + disk.name
"Disk #" + (index + 1) + ": " + disk.getDiskName()
));
// Disk info row
long usedSpace = disk.getItemCount();
long totalSpace = disk.getMaxSlots() * 64L;
commands.append(prefix + "_info", createInfoRow(
"Items: " + disk.itemCount + " types",
disk.usedSpace + " / " + disk.totalSpace + " used"
"Items: " + disk.getDistinctItemTypes() + " types",
usedSpace + " / " + totalSpace + " items"
));
// Usage bar placeholder
double usagePct = disk.totalSpace > 0
? (double) disk.usedSpace / disk.totalSpace * 100
: 0;
// Usage bar
double usagePct = totalSpace > 0 ? (double) usedSpace / totalSpace * 100 : 0;
commands.append(prefix + "_usageBar", createUsageBar(usagePct));
// Priority slider
commands.append(prefix + "_priority", createPrioritySlider(index, disk.priority));
commands.append(prefix + "_priority", createPrioritySlider(index, disk.getPriority()));
// Action buttons row
commands.append(prefix + "_formatBtn", createActionButton("Format", "format_" + index));
@ -203,10 +224,9 @@ public class DiskDriveUI extends CustomUIPage {
private String createUsageBar(double percentage) {
int filledBars = Math.min(10, Math.max(0, (int) (percentage / 10)));
int emptyBars = 10 - filledBars;
StringBuilder bar = new StringBuilder("[");
for (int i = 0; i < filledBars; i++) bar.append("\u2588");
for (int i = 0; i < emptyBars; i++) bar.append("\u2591");
for (int i = 0; i < 10 - filledBars; i++) bar.append("\u2591");
bar.append("] ").append(String.format("%.0f", percentage)).append("%");
return "{" +
@ -248,23 +268,4 @@ public class DiskDriveUI extends CustomUIPage {
.replace("\r", "\\r")
.replace("\t", "\\t");
}
/**
* Internal representation of a storage disk in the drive bay.
*/
public static class DiskEntry {
public final String name;
public final long usedSpace;
public final long totalSpace;
public final int itemCount;
public final int priority;
public DiskEntry(String name, long usedSpace, long totalSpace, int itemCount, int priority) {
this.name = name;
this.usedSpace = usedSpace;
this.totalSpace = totalSpace;
this.itemCount = itemCount;
this.priority = priority;
}
}
}

View file

@ -29,7 +29,6 @@ public final class UIManager {
public void openGrid(PlayerRef playerRef, String networkId) {
LOGGER.atInfo().log("Opening Grid UI for player %s (network %s)", playerRef, networkId);
CustomUIPage page = new GridUI(playerRef, networkId);
// The page opens automatically via CustomUIPage's lifecycle
}
/**
@ -41,11 +40,12 @@ public final class UIManager {
}
/**
* Open the disk drive management UI for a player.
* Open the disk drive management UI for a player at a specific drive position.
*/
public void openDiskDrive(PlayerRef playerRef, String networkId) {
LOGGER.atInfo().log("Opening DiskDrive UI for player %s (network %s)", playerRef, networkId);
CustomUIPage page = new DiskDriveUI(playerRef, networkId);
public void openDiskDrive(PlayerRef playerRef, String networkId, Vector3i drivePos) {
LOGGER.atInfo().log("Opening DiskDrive UI for player %s (network %s) at (%s,%s,%s)",
playerRef, networkId, drivePos.x, drivePos.y, drivePos.z);
CustomUIPage page = new DiskDriveUI(playerRef, networkId, drivePos);
}
/**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 913 B

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 B

After

Width:  |  Height:  |  Size: 913 B

View file

@ -1,8 +1,151 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "Items/advanced_processor/model_texture"
}
}
"nodes": [
{
"id": "root",
"name": "Origin",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "none",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"isPiece": false
},
"textureLayout": {},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": [
{
"id": "item_shape",
"name": "ItemShape",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "box",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"size": {
"x": 16,
"y": 16,
"z": 1
}
},
"textureLayout": {
"top": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"bottom": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"front": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"back": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"left": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"right": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
}
},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": []
}
]
}
],
"lod": "auto"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 913 B

After

Width:  |  Height:  |  Size: 895 B

View file

@ -1,8 +1,151 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "Items/construction_core/model_texture"
}
}
"nodes": [
{
"id": "root",
"name": "Origin",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "none",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"isPiece": false
},
"textureLayout": {},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": [
{
"id": "item_shape",
"name": "ItemShape",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "box",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"size": {
"x": 16,
"y": 16,
"z": 1
}
},
"textureLayout": {
"top": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"bottom": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"front": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"back": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"left": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"right": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
}
},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": []
}
]
}
],
"lod": "auto"
}

View file

@ -1,8 +1,151 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "Items/network_tool/model_texture"
}
}
"nodes": [
{
"id": "root",
"name": "Origin",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "none",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"isPiece": false
},
"textureLayout": {},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": [
{
"id": "item_shape",
"name": "ItemShape",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "box",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"size": {
"x": 16,
"y": 16,
"z": 1
}
},
"textureLayout": {
"top": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"bottom": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"front": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"back": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"left": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"right": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
}
},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": []
}
]
}
],
"lod": "auto"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 B

After

Width:  |  Height:  |  Size: 179 B

View file

@ -1,8 +1,151 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "Items/pattern/model_texture"
}
}
"nodes": [
{
"id": "root",
"name": "Origin",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "none",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"isPiece": false
},
"textureLayout": {},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": [
{
"id": "item_shape",
"name": "ItemShape",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "box",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"size": {
"x": 16,
"y": 16,
"z": 1
}
},
"textureLayout": {
"top": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"bottom": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"front": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"back": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"left": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"right": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
}
},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": []
}
]
}
],
"lod": "auto"
}

View file

@ -1,8 +1,151 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "Items/printed_processor/model_texture"
}
}
"nodes": [
{
"id": "root",
"name": "Origin",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "none",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"isPiece": false
},
"textureLayout": {},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": [
{
"id": "item_shape",
"name": "ItemShape",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "box",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"size": {
"x": 16,
"y": 16,
"z": 1
}
},
"textureLayout": {
"top": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"bottom": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"front": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"back": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"left": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"right": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
}
},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": []
}
]
}
],
"lod": "auto"
}

View file

@ -1,8 +1,151 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "Items/raw_processor/model_texture"
}
}
"nodes": [
{
"id": "root",
"name": "Origin",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "none",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"isPiece": false
},
"textureLayout": {},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": [
{
"id": "item_shape",
"name": "ItemShape",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "box",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"size": {
"x": 16,
"y": 16,
"z": 1
}
},
"textureLayout": {
"top": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"bottom": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"front": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"back": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"left": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"right": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
}
},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": []
}
]
}
],
"lod": "auto"
}

View file

@ -1,8 +1,151 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "Items/security_card/model_texture"
}
}
"nodes": [
{
"id": "root",
"name": "Origin",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "none",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"isPiece": false
},
"textureLayout": {},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": [
{
"id": "item_shape",
"name": "ItemShape",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "box",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"size": {
"x": 16,
"y": 16,
"z": 1
}
},
"textureLayout": {
"top": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"bottom": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"front": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"back": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"left": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"right": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
}
},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": []
}
]
}
],
"lod": "auto"
}

View file

@ -1,8 +1,151 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "Items/storage_disk/model_texture"
}
}
"nodes": [
{
"id": "root",
"name": "Origin",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "none",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"isPiece": false
},
"textureLayout": {},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": [
{
"id": "item_shape",
"name": "ItemShape",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "box",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"size": {
"x": 16,
"y": 16,
"z": 1
}
},
"textureLayout": {
"top": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"bottom": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"front": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"back": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"left": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"right": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
}
},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": []
}
]
}
],
"lod": "auto"
}

View file

@ -1,8 +1,151 @@
{
"format_version": 1,
"parent": "hytale:item/generated",
"textures": {
"layer0": "Items/upgrade_fortune/model_texture"
}
}
"nodes": [
{
"id": "root",
"name": "Origin",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "none",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"isPiece": false
},
"textureLayout": {},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": [
{
"id": "item_shape",
"name": "ItemShape",
"position": {
"x": 0,
"y": 0,
"z": 0
},
"orientation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"shape": {
"type": "box",
"offset": {
"x": 0,
"y": 0,
"z": 0
},
"stretch": {
"x": 1,
"y": 1,
"z": 1
},
"settings": {
"size": {
"x": 16,
"y": 16,
"z": 1
}
},
"textureLayout": {
"top": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"bottom": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"front": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"back": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"left": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
},
"right": {
"offset": {
"x": 0,
"y": 0
},
"mirror": {
"x": false,
"y": false
},
"angle": 0
}
},
"unwrapMode": "custom",
"visible": true,
"doubleSided": false,
"shadingMode": "flat"
},
"children": []
}
]
}
],
"lod": "auto"
}

Some files were not shown because too many files have changed in this diff Show more