diff options
Diffstat (limited to 'codegen/lib')
| -rwxr-xr-x | codegen/lib/code/shapes.py | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/codegen/lib/code/shapes.py b/codegen/lib/code/shapes.py index f270fd7f..6906328c 100755 --- a/codegen/lib/code/shapes.py +++ b/codegen/lib/code/shapes.py @@ -72,6 +72,7 @@ def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report, for (shape_id, shape) in sorted(shapes.items(), key=lambda shape: int(shape[0])): generated_shape_code += generate_code_for_shape(shape_id, shape) + # 1..100 | 200..300 => &SHAPE1, generated_match_inner_code = '' shape_ids_to_block_state_ids = {} @@ -79,7 +80,6 @@ def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report, if isinstance(shape_ids, int): shape_ids = [shape_ids] block_report_data = block_states_report['minecraft:' + block_id] - block_data_burger = block_datas_burger[block_id] for possible_state, shape_id in zip(block_report_data['states'], shape_ids): block_state_id = possible_state['id'] @@ -87,30 +87,20 @@ def generate_block_shapes_code(blocks: dict, shapes: dict, block_states_report, if shape_id not in shape_ids_to_block_state_ids: shape_ids_to_block_state_ids[shape_id] = [] shape_ids_to_block_state_ids[shape_id].append(block_state_id) + + empty_shape_match_code = convert_ints_to_rust_ranges(shape_ids_to_block_state_ids[0]) + block_shape_match_code = convert_ints_to_rust_ranges(shape_ids_to_block_state_ids[1]) + # shape 1 is the most common so we have a _ => &SHAPE1 at the end del shape_ids_to_block_state_ids[1] - for shape_id, block_state_ids in shape_ids_to_block_state_ids.items(): - - # convert them into ranges (so like 1|2|3 is 1..=3 instead) - block_state_ids_ranges = [] - range_start_block_state_id = None - last_block_state_id = None - for block_state_id in sorted(block_state_ids): - if range_start_block_state_id is None: - range_start_block_state_id = block_state_id - - if last_block_state_id is not None: - # check if the range is done - if block_state_id - 1 != last_block_state_id: - block_state_ids_ranges.append(f'{range_start_block_state_id}..={last_block_state_id}' if range_start_block_state_id != last_block_state_id else str(range_start_block_state_id)) - range_start_block_state_id = block_state_id - - last_block_state_id = block_state_id - block_state_ids_ranges.append(f'{range_start_block_state_id}..={last_block_state_id}' if range_start_block_state_id != last_block_state_id else str(range_start_block_state_id)) - generated_match_inner_code += f'{"|".join(block_state_ids_ranges)} => &SHAPE{shape_id},\n' + for shape_id, block_state_ids in shape_ids_to_block_state_ids.items(): + generated_match_inner_code += f'{convert_ints_to_rust_ranges(block_state_ids)} => &SHAPE{shape_id},\n' generated_match_inner_code += '_ => &SHAPE1' + if empty_shape_match_code == '': + print('Error: shape 0 was not found') + return f''' //! Autogenerated block collisions for every block @@ -127,6 +117,11 @@ use once_cell::sync::Lazy; pub trait BlockWithShape {{ fn shape(&self) -> &'static VoxelShape; + /// Tells you whether the block has an empty shape. + /// + /// This is slightly more efficient than calling `shape()` and comparing against `EMPTY_SHAPE`. + fn is_shape_empty(&self) -> bool; + fn is_shape_full(&self) -> bool; }} {generated_shape_code} @@ -137,6 +132,14 @@ impl BlockWithShape for BlockState {{ {generated_match_inner_code} }} }} + + fn is_shape_empty(&self) -> bool {{ + matches!(self.id, {empty_shape_match_code}) + }} + + fn is_shape_full(&self) -> bool {{ + matches!(self.id, {block_shape_match_code}) + }} }} ''' @@ -165,3 +168,23 @@ def generate_code_for_shape(shape_id: str, parts: list[list[float]]): code += '}\n' code += '});\n' return code + +def convert_ints_to_rust_ranges(block_state_ids: list[int]) -> str: + # convert them into ranges (so like 1|2|3 is 1..=3 instead) + block_state_ids_ranges = [] + range_start_block_state_id = None + last_block_state_id = None + for block_state_id in sorted(block_state_ids): + if range_start_block_state_id is None: + range_start_block_state_id = block_state_id + + if last_block_state_id is not None: + # check if the range is done + if block_state_id - 1 != last_block_state_id: + block_state_ids_ranges.append(f'{range_start_block_state_id}..={last_block_state_id}' if range_start_block_state_id != last_block_state_id else str(range_start_block_state_id)) + range_start_block_state_id = block_state_id + + last_block_state_id = block_state_id + + block_state_ids_ranges.append(f'{range_start_block_state_id}..={last_block_state_id}' if range_start_block_state_id != last_block_state_id else str(range_start_block_state_id)) + return '|'.join(block_state_ids_ranges) |
