mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
feat: add block state data to all palettes
This commit is contained in:
parent
f1d844afbe
commit
cfb77088b6
21 changed files with 57289 additions and 26 deletions
|
|
@ -17,23 +17,39 @@ import json
|
|||
import math
|
||||
import re
|
||||
import sys
|
||||
from collections.abc import Sequence
|
||||
from pathlib import Path
|
||||
|
||||
OUTPUT_DIR = (Path(__file__).resolve().parent.parent /
|
||||
"MinecraftClient" / "Mapping" / "BlockPalettes")
|
||||
MATERIAL_CS = OUTPUT_DIR.parent / "Material.cs"
|
||||
|
||||
# Minecraft renamed these registry keys after the corresponding MCC Material
|
||||
# names had already stabilized. Keep historical reports mapped to the current
|
||||
# enum names instead of generating references to members that do not exist.
|
||||
MATERIAL_NAME_ALIASES = {
|
||||
"Grass": "ShortGrass",
|
||||
"GrassPath": "DirtPath",
|
||||
"Sign": "OakSign",
|
||||
"WallSign": "OakWallSign",
|
||||
}
|
||||
|
||||
OUTPUT_FILE_ALIASES = {
|
||||
"120": "BlockPalette120.cs",
|
||||
}
|
||||
|
||||
|
||||
def mc_name_to_csharp(mc_name: str) -> str:
|
||||
"""Convert minecraft:snake_case to PascalCase C# enum name."""
|
||||
name = mc_name.removeprefix("minecraft:")
|
||||
return "".join(word.capitalize() for word in name.split("_"))
|
||||
csharp_name = "".join(word.capitalize() for word in name.split("_"))
|
||||
return MATERIAL_NAME_ALIASES.get(csharp_name, csharp_name)
|
||||
|
||||
|
||||
def load_known_materials() -> set[str]:
|
||||
known = set()
|
||||
if MATERIAL_CS.exists():
|
||||
with open(MATERIAL_CS) as f:
|
||||
with MATERIAL_CS.open(encoding="utf-8-sig") as f:
|
||||
for line in f:
|
||||
m = re.match(r'\s+(\w+),?\s*$', line)
|
||||
if m:
|
||||
|
|
@ -89,6 +105,74 @@ def csharp_string(value: str) -> str:
|
|||
return json.dumps(value, ensure_ascii=False)
|
||||
|
||||
|
||||
def render_state_definitions(
|
||||
block_ranges: Sequence[tuple[int, int, str, list[tuple[str, list[str], int]]]],
|
||||
) -> tuple[list[str], int]:
|
||||
"""Render the generated state-property section and return its definition count."""
|
||||
lines = [
|
||||
" // <auto-generated block-state-properties>",
|
||||
" private static readonly BlockStateDefinition[] stateDefinitions =",
|
||||
" [",
|
||||
]
|
||||
property_definition_count = 0
|
||||
for min_s, max_s, _, properties in block_ranges:
|
||||
if not properties:
|
||||
continue
|
||||
|
||||
property_definition_count += 1
|
||||
lines.append(f" new({min_s}, {max_s - min_s + 1},")
|
||||
lines.append(" [")
|
||||
for index, (name, values, stride) in enumerate(properties):
|
||||
encoded_values = ", ".join(csharp_string(value) for value in values)
|
||||
suffix = "," if index < len(properties) - 1 else ""
|
||||
lines.append(f" new({csharp_string(name)}, [{encoded_values}], {stride}){suffix}")
|
||||
lines.append(" ]),")
|
||||
|
||||
lines += [
|
||||
" ];",
|
||||
" // </auto-generated block-state-properties>",
|
||||
]
|
||||
return lines, property_definition_count
|
||||
|
||||
|
||||
def update_existing_palette(output_path: Path, state_lines: list[str]) -> bool:
|
||||
"""Replace only generated state metadata while preserving established material mappings."""
|
||||
if not output_path.exists():
|
||||
return False
|
||||
|
||||
source = output_path.read_text(encoding="utf-8")
|
||||
dictionary_method = " protected override Dictionary<int, Material> GetDict()"
|
||||
dictionary_index = source.find(dictionary_method)
|
||||
if dictionary_index < 0:
|
||||
raise ValueError(f"{output_path} does not contain the expected GetDict method")
|
||||
|
||||
generated_start = source.find(" // <auto-generated block-state-properties>")
|
||||
legacy_start = source.find(" private static readonly BlockStateDefinition[] stateDefinitions =")
|
||||
section_start = generated_start if generated_start >= 0 else legacy_start
|
||||
if section_start < 0:
|
||||
section_start = dictionary_index
|
||||
|
||||
prefix = source[:section_start].rstrip()
|
||||
suffix = source[dictionary_index:]
|
||||
state_override = """ protected override BlockStateDefinition[] GetStateDefinitions()
|
||||
{
|
||||
return stateDefinitions;
|
||||
}
|
||||
"""
|
||||
suffix = suffix.replace("\n" + state_override, "", 1)
|
||||
|
||||
class_end = suffix.rfind("\n }\n}")
|
||||
if class_end < 0:
|
||||
raise ValueError(f"{output_path} does not contain the expected class terminator")
|
||||
suffix = suffix[:class_end].rstrip() + "\n\n" + state_override.rstrip() + suffix[class_end:]
|
||||
|
||||
output_path.write_text(
|
||||
prefix + "\n\n" + "\n".join(state_lines) + "\n\n" + suffix,
|
||||
encoding="utf-8",
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
print(__doc__)
|
||||
|
|
@ -101,7 +185,7 @@ def main():
|
|||
print(f"Error: {blocks_json} not found")
|
||||
sys.exit(1)
|
||||
|
||||
with open(blocks_json) as f:
|
||||
with blocks_json.open(encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Build block ranges and compact state-property definitions, sorted by min state.
|
||||
|
|
@ -130,7 +214,15 @@ def main():
|
|||
print("Insert them in alphabetical order within the enum.")
|
||||
|
||||
class_name = f"Palette{class_suffix}"
|
||||
output_path = OUTPUT_DIR / f"{class_name}.cs"
|
||||
output_path = OUTPUT_DIR / OUTPUT_FILE_ALIASES.get(class_suffix, f"{class_name}.cs")
|
||||
state_lines, property_definition_count = render_state_definitions(block_ranges)
|
||||
|
||||
if update_existing_palette(output_path, state_lines):
|
||||
print(
|
||||
f"Updated {output_path} with {property_definition_count} property definitions "
|
||||
"while preserving material mappings"
|
||||
)
|
||||
return
|
||||
|
||||
lines = [
|
||||
"using System.Collections.Generic;",
|
||||
|
|
@ -152,28 +244,10 @@ def main():
|
|||
lines += [
|
||||
" }",
|
||||
"",
|
||||
" private static readonly BlockStateDefinition[] stateDefinitions =",
|
||||
" [",
|
||||
]
|
||||
|
||||
property_definition_count = 0
|
||||
for min_s, max_s, _, properties in block_ranges:
|
||||
if not properties:
|
||||
continue
|
||||
|
||||
property_definition_count += 1
|
||||
lines.append(f" new({min_s}, {max_s - min_s + 1},")
|
||||
lines.append(" [")
|
||||
property_items = properties
|
||||
for index, (name, values, stride) in enumerate(property_items):
|
||||
encoded_values = ", ".join(csharp_string(value) for value in values)
|
||||
suffix = "," if index < len(property_items) - 1 else ""
|
||||
lines.append(f" new({csharp_string(name)}, [{encoded_values}], {stride}){suffix}")
|
||||
lines.append(" ]),")
|
||||
|
||||
lines += [
|
||||
" ];",
|
||||
*state_lines,
|
||||
"",
|
||||
]
|
||||
lines += [
|
||||
" protected override Dictionary<int, Material> GetDict()",
|
||||
" {",
|
||||
" return materials;",
|
||||
|
|
@ -188,7 +262,7 @@ def main():
|
|||
"",
|
||||
]
|
||||
|
||||
output_path.write_text("\n".join(lines))
|
||||
output_path.write_text("\n".join(lines), encoding="utf-8")
|
||||
print(
|
||||
f"Generated {output_path} with {len(block_ranges)} blocks, "
|
||||
f"{max_state + 1} total states, and {property_definition_count} property definitions"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue