From d8c5775f13dec7b739b405b71f2db5063cd0c9fe Mon Sep 17 00:00:00 2001 From: theogiraudet Date: Sun, 26 Jan 2025 17:23:04 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20bs.block:play=5Fblock?= =?UTF-8?q?=5Fsound=20(#310)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/definitions.py | 1 + docs/_templates/changelog/v3.0.0.md | 5 ++ docs/modules/block.md | 52 +++++++++++++++++++ meta/manifest.json | 15 ++++++ .../block_sound/play_block_sound.mcfunction | 16 ++++++ .../produce/block_sound/run.mcfunction | 16 ++++++ .../tags/function/play_block_sound.json | 20 +++++++ modules/bs.block/gen_blocks.py | 19 +++++-- 8 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 modules/bs.block/data/bs.block/function/produce/block_sound/play_block_sound.mcfunction create mode 100644 modules/bs.block/data/bs.block/function/produce/block_sound/run.mcfunction create mode 100644 modules/bs.block/data/bs.block/tags/function/play_block_sound.json diff --git a/core/definitions.py b/core/definitions.py index 940499b622..9ec84f7805 100644 --- a/core/definitions.py +++ b/core/definitions.py @@ -29,6 +29,7 @@ BIOMES_URL = "https://raw.githubusercontent.com/misode/mcmeta/{}-summary/data/worldgen/biome/data.min.json" BLOCKS_URL = "https://raw.githubusercontent.com/misode/mcmeta/{}-summary/blocks/data.min.json" ITEMS_URL = "https://raw.githubusercontent.com/misode/mcmeta/{}-registries/item/data.min.json" +SOUNDS_URL = "https://raw.githubusercontent.com/mcbookshelf/Bookshelf-McData/refs/tags/{}/blocks/sounds.min.json" SHAPES_URL = "https://raw.githubusercontent.com/mcbookshelf/Bookshelf-McData/refs/tags/{}/blocks/shapes.min.json" VERSION_URL = "https://raw.githubusercontent.com/misode/mcmeta/refs/tags/{}-summary/version.json" diff --git a/docs/_templates/changelog/v3.0.0.md b/docs/_templates/changelog/v3.0.0.md index 016e775097..2b8ba43b01 100644 --- a/docs/_templates/changelog/v3.0.0.md +++ b/docs/_templates/changelog/v3.0.0.md @@ -20,6 +20,11 @@ - ⚙️ **[#285](https://github.com/mcbookshelf/Bookshelf/pull/285)** - Added new workflows with automatic deployment to **Modrinth** and **Smithed**. +### `🧱 bs.block` + +- **[#279](https://github.com/mcbookshelf/Bookshelf/issues/279)** - Added a `#bs.block:play_block_sound` tag for playing block sounds. + + ### `🎯 bs.hitbox` - ⚠️ **[#297](https://github.com/mcbookshelf/Bookshelf/issues/297)** - Renamed block tag `is_composite` to `not_full_cube` for better clarity. diff --git a/docs/modules/block.md b/docs/modules/block.md index dd5a5456c9..7913f605fe 100644 --- a/docs/modules/block.md +++ b/docs/modules/block.md @@ -183,6 +183,12 @@ Get all data related to the block at the current location, including its state a - {nbt}`string` **state**: Represent the state of a block (e.g., `[shape=straight]`). - {nbt}`compound` **nbt**: Data tags used by block entities or an empty string. - {nbt}`compound` **properties**: Block state as properties (used by entities like falling blocks). + - {nbt}`compound` **sounds**: The sound list of a block. + - {nbt}`string` **break**: The sound played when a player break the block. + - {nbt}`string` **hit**: The sound played when a player hit the block. + - {nbt}`string` **fall**: The sound played when a player fall on the block. + - {nbt}`string` **place**: The sound played when a player place the block. + - {nbt}`string` **step**: The sound played when a player step on the block. ::: ``` @@ -217,6 +223,12 @@ Get the block type at the current location. Although states, NBTs, and propertie - {nbt}`string` **state**: Represent the state of a block **[empty string]**. - {nbt}`compound` **nbt**: Data tags used by block entities **[empty string]**. - {nbt}`compound` **properties**: Block state as properties **[empty compound]**. + - {nbt}`compound` **sounds**: The sound list of a block. + - {nbt}`string` **break**: The sound played when a player break the block. + - {nbt}`string` **hit**: The sound played when a player hit the block. + - {nbt}`string` **fall**: The sound played when a player fall on the block. + - {nbt}`string` **place**: The sound played when a player place the block. + - {nbt}`string` **step**: The sound played when a player step on the block. ::: ``` @@ -893,6 +905,46 @@ data modify storage bs:in block.emit_block_particle merge value { delta: "0 0 0" function #bs.block:emit_block_particle ``` +:::: +::::{tab-item} Block Sound + +```{function} #bs.block:play_block_sound + +Play a block sound of the given block. + +:Inputs: + **Execution `at ` or `positioned `**: Position where the sound will be played. + + **Storage `bs:in block.play_block_sound`**: + :::{treeview} + - {nbt}`compound` Block sound data + - {nbt}`string` **sound**: The sound to play. Usually took from the `sounds` property of the virtual block (cf get functions). + - {nbt}`string` **source**: The source of the sound. Similar to the /playsound command. + - {nbt}`string` **targets**: The targets of the sound. Similar to the /playsound command. + - {nbt}`string` **pos**: X Y Z coordinates, the position of the sound. Similar to the /playsound command. + - {nbt}`int` **volume**: Volume of the sound. Similar to the /playsound command. + - {nbt}`int` **pitch**: Pitch of the sound. Similar to the /playsound command. + - {nbt}`int` **min_volume**: Minimum volume of the sound. Similar to the /playsound command. + ::: + +:Outputs: + **State**: The sound is played. +``` + +*Play the sound of the block at 0 0 0:* + +```mcfunction +# Get block data +execute positioned 0 0 0 run function #bs.block:get_block + +# Setup the input +data modify storage bs:in block.play_block_sound set value { source: "block", targets: "@s", pos: "~ ~ ~", volume: 1, pitch: 1, min_volume: 0 } +data modify storage bs:in block.play_block_sound.sound set from storage bs:out block.sounds.break + +# Play the block sound +function #bs.block:play_block_sound +``` + :::: ::::: diff --git a/meta/manifest.json b/meta/manifest.json index 3a0b2cf32d..b13bcaa04a 100644 --- a/meta/manifest.json +++ b/meta/manifest.json @@ -345,6 +345,21 @@ "minecraft_version": "1.20.6" } }, + { + "id": "#bs.block:play_block_sound", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/block.html#produce", + "authors": [ + "theogiraudet" + ], + "created": { + "date": "2025/01/25", + "minecraft_version": "1.21.4" + }, + "updated": { + "date": "2025/01/25", + "minecraft_version": "1.21.4" + } + }, { "id": "#bs.block:remove_properties", "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/block.html#manage-state", diff --git a/modules/bs.block/data/bs.block/function/produce/block_sound/play_block_sound.mcfunction b/modules/bs.block/data/bs.block/function/produce/block_sound/play_block_sound.mcfunction new file mode 100644 index 0000000000..a2f3515adb --- /dev/null +++ b/modules/bs.block/data/bs.block/function/produce/block_sound/play_block_sound.mcfunction @@ -0,0 +1,16 @@ +# ------------------------------------------------------------------------------------------------------------ +# Copyright (c) 2025 Gunivers +# +# This file is part of the Bookshelf project (https://github.com/mcbookshelf/Bookshelf). +# +# This source code is subject to the terms of the Mozilla Public License, v. 2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# Conditions: +# - You may use this file in compliance with the MPL v2.0 +# - Any modifications must be documented and disclosed under the same license +# +# For more details, refer to the MPL v2.0. +# ------------------------------------------------------------------------------------------------------------ + +function bs.block:produce/block_sound/run with storage bs:in block.play_block_sound diff --git a/modules/bs.block/data/bs.block/function/produce/block_sound/run.mcfunction b/modules/bs.block/data/bs.block/function/produce/block_sound/run.mcfunction new file mode 100644 index 0000000000..832eb2c456 --- /dev/null +++ b/modules/bs.block/data/bs.block/function/produce/block_sound/run.mcfunction @@ -0,0 +1,16 @@ +# ------------------------------------------------------------------------------------------------------------ +# Copyright (c) 2025 Gunivers +# +# This file is part of the Bookshelf project (https://github.com/mcbookshelf/Bookshelf). +# +# This source code is subject to the terms of the Mozilla Public License, v. 2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# Conditions: +# - You may use this file in compliance with the MPL v2.0 +# - Any modifications must be documented and disclosed under the same license +# +# For more details, refer to the MPL v2.0. +# ------------------------------------------------------------------------------------------------------------ + +$playsound $(sound) $(source) $(targets) $(pos) $(volume) $(pitch) $(min_volume) diff --git a/modules/bs.block/data/bs.block/tags/function/play_block_sound.json b/modules/bs.block/data/bs.block/tags/function/play_block_sound.json new file mode 100644 index 0000000000..df5d64e10b --- /dev/null +++ b/modules/bs.block/data/bs.block/tags/function/play_block_sound.json @@ -0,0 +1,20 @@ +{ + "__bookshelf__": { + "feature": true, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/block.html#produce", + "authors": [ + "theogiraudet" + ], + "created": { + "date": "2025/01/25", + "minecraft_version": "1.21.4" + }, + "updated": { + "date": "2025/01/25", + "minecraft_version": "1.21.4" + } + }, + "values": [ + "bs.block:produce/block_sound/play_block_sound" + ] +} diff --git a/modules/bs.block/gen_blocks.py b/modules/bs.block/gen_blocks.py index d7c068a154..af5172a3c4 100644 --- a/modules/bs.block/gen_blocks.py +++ b/modules/bs.block/gen_blocks.py @@ -5,6 +5,7 @@ import numpy as np from beet import BlockTag, Context, Function, LootTable +from core.common.logger import log_step from pydantic import BaseModel from core.common.helpers import ( @@ -19,6 +20,7 @@ BLOCKS_URL, ITEMS_URL, MINECRAFT_VERSIONS, + SOUNDS_URL, SPECIAL_ITEMS, ) @@ -26,6 +28,7 @@ type StatesDict = dict[str, list[str]] type StatesTuple = tuple[tuple[str, tuple[str, ...]], ...] type RawBlocks = dict[str, tuple[StatesDict, StrDict]] +type RawSounds = dict[str, dict[str, str]] class Block(BaseModel): """Represents a Minecraft block.""" @@ -33,6 +36,7 @@ class Block(BaseModel): type: str item: str | None group: int + sounds: dict[str, str] states: list["State"] class State(BaseModel): @@ -95,25 +99,32 @@ def get_optimized_blocks() -> list: error_msg = f"Expected a list, but got {type(raw_items)}" raise TypeError(error_msg) + raw_sounds = download_and_parse_json(cache, SOUNDS_URL.format(version)) + if not isinstance(raw_sounds, dict): + error_msg = f"Expected a dict, but got {type(raw_sounds)}" + raise TypeError(error_msg) + items = { with_prefix(item): with_prefix(item) for item in raw_items } | SPECIAL_ITEMS - return group_and_optimize_blocks(raw_blocks, items) + return group_and_optimize_blocks(raw_blocks, items, raw_sounds) return [Block.model_validate(data) for data in get_optimized_blocks()] -def group_and_optimize_blocks(raw_blocks: RawBlocks, items: StrDict) -> list: +def group_and_optimize_blocks(raw_blocks: RawBlocks, items: StrDict, raw_sounds: RawSounds) -> list: """Group blocks and optimizes block state sequences.""" blocks: list[dict] = [] groups: dict[StatesTuple, int] = {(): 0} for block, (states, properties) in raw_blocks.items(): ordered_states = reorder_states_options(states, properties) + prefixed_block = with_prefix(block) insort(blocks, { - "type": with_prefix(block), - "item": items.get(with_prefix(block)), + "type": prefixed_block, + "item": items.get(prefixed_block), + "sounds": raw_sounds.get(prefixed_block, {}), "group": groups.setdefault(ordered_states, len(groups)), }, key=lambda x: x["group"])