diff options
Diffstat (limited to 'codegen/lib/code')
| -rw-r--r-- | codegen/lib/code/blocks.py | 96 | ||||
| -rw-r--r-- | codegen/lib/code/version.py | 3 |
2 files changed, 98 insertions, 1 deletions
diff --git a/codegen/lib/code/blocks.py b/codegen/lib/code/blocks.py new file mode 100644 index 00000000..bc5083c7 --- /dev/null +++ b/codegen/lib/code/blocks.py @@ -0,0 +1,96 @@ +from lib.utils import get_dir_location +from lib.utils import to_camel_case +from ..mappings import Mappings +import json + +BLOCKS_RS_DIR = get_dir_location('../azalea-block/src/blocks.rs') + +# Terminology: +# - Property: A property of a block, like "direction" +# - Variant: A potential state of a property, like "up" +# - State: A possible state of a block, a combination of variants +# - Block: Has properties and states. + + +def get_property_variants(data) -> list[str]: + if 'values' in data: + return list(map(str.lower, data['values'])) + if data['type'] == 'bool': + return ['true', 'false'] + if data['type'] == 'int': + # range between data['min'] and data['max'] + return [str(i) for i in range(data['min'], data['max'] + 1)] + raise Exception('Unknown property type: ' + data['type']) + + +def generate_blocks(blocks: dict, mappings: Mappings): + with open(BLOCKS_RS_DIR, 'r') as f: + existing_code = f.read().splitlines() + + new_make_block_states_macro_code = [] + new_make_block_states_macro_code.append('make_block_states! {') + + # Find properties + properties = {} + for block_data in blocks.values(): + block_properties = {} + for property in block_data.get('states', []): + property_name = mappings.get_field( + property.get('declared_in', block_data['class']), property['field_name']).lower() + property_variants = get_property_variants(property) + block_properties[property_name] = property_variants + # if property_name == 'eggs': + # print(property, property_name, property_variants) + properties.update(block_properties) + + # Property codegen + new_make_block_states_macro_code.append(' Properties => {') + for property_name, property_variants in properties.items(): + new_make_block_states_macro_code.append( + f' {to_camel_case(property_name)} {{') + + for variant in property_variants: + new_make_block_states_macro_code.append( + f' {to_camel_case(variant)},') + + new_make_block_states_macro_code.append( + f' }},') + new_make_block_states_macro_code.append(' },') + + # Block codegen + new_make_block_states_macro_code.append(' Blocks => {') + for block_id, block_data in blocks.items(): + block_states = block_data['states'] + + default_property_variants = {} + for state in block_states: + if state.get('default'): + default_property_variants = state.get('properties', {}) + + # TODO: use burger to generate the blockbehavior + new_make_block_states_macro_code.append( + f' {block_id} => BlockBehavior::default(), {{') + for property in block_data.get('properties', {}): + property_default = default_property_variants.get(property) + new_make_block_states_macro_code.append( + f' {to_camel_case(property)}={to_camel_case(property_default)},') + new_make_block_states_macro_code.append(' },') + new_make_block_states_macro_code.append(' }') + new_make_block_states_macro_code.append('}') + + new_code = [] + in_macro = False + for line in existing_code: + if line == 'make_block_states! {': + in_macro = True + elif line == '}': + if in_macro: + in_macro = False + new_code.extend(new_make_block_states_macro_code) + continue + if in_macro: + continue + new_code.append(line) + + with open(BLOCKS_RS_DIR, 'w') as f: + f.write('\n'.join(new_code)) diff --git a/codegen/lib/code/version.py b/codegen/lib/code/version.py index e131a598..4c8500be 100644 --- a/codegen/lib/code/version.py +++ b/codegen/lib/code/version.py @@ -1,7 +1,8 @@ import re import os +from lib.utils import get_dir_location -README_DIR = os.path.join(os.path.dirname(__file__), '../../../README.md') +README_DIR = get_dir_location('../README.md') VERSION_REGEX = r'\*Currently supported Minecraft version: `(.*)`.\*' |
