diff --git a/.github/workflows/review.yml b/.github/workflows/review.yml index 6f480dafe4..a0c6a32256 100644 --- a/.github/workflows/review.yml +++ b/.github/workflows/review.yml @@ -3,7 +3,13 @@ name: 📋 Modules Review on: push: branches: ["master"] + paths: + - "modules/**" + - "src/**" pull_request: + paths: + - "modules/**" + - "src/**" workflow_call: workflow_dispatch: diff --git a/.spyglassrc.json b/.spyglassrc.json index 837a4f3350..aaf8e6900d 100644 --- a/.spyglassrc.json +++ b/.spyglassrc.json @@ -3,11 +3,11 @@ "useFilePolling": false, "exclude": [ ".*/**", - "bookshelf/**", "build/**", "data/**", "docs/**", - "release/**" + "release/**", + "src/**" ], "mcmetaSummaryOverrides": { "commands": { diff --git a/data/manifest.json b/data/manifest.json index 6d2124f11b..cdebbb5890 100644 --- a/data/manifest.json +++ b/data/manifest.json @@ -1801,6 +1801,22 @@ "minecraft_version": "1.21.4" } }, + { + "id": "#bs.hitbox:is_fluid", + "kind": "block_tag", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#blocks", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, { "id": "#bs.hitbox:is_full_cube", "kind": "block_tag", @@ -1817,6 +1833,38 @@ "minecraft_version": "1.21.4" } }, + { + "id": "#bs.hitbox:is_waterloggable", + "kind": "block_tag", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#blocks", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + { + "id": "#bs.hitbox:none", + "kind": "block_tag", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#blocks", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, { "id": "#bs.hitbox:intangible", "kind": "entity_type_tag", @@ -1884,7 +1932,7 @@ { "id": "#bs.hitbox:get_block", "kind": "function_tag", - "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#get", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#get-block", "authors": [ "Aksiome" ], @@ -1932,7 +1980,7 @@ { "id": "#bs.hitbox:get_entity", "kind": "function_tag", - "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#get", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#get-entity", "authors": [ "Aksiome" ], @@ -3567,8 +3615,8 @@ "minecraft_version": "1.13" }, "updated": { - "date": "2025/10/06", - "minecraft_version": "1.21.9" + "date": "2025/11/23", + "minecraft_version": "1.21.10" } }, { @@ -3584,8 +3632,8 @@ "minecraft_version": "1.13" }, "updated": { - "date": "2025/10/06", - "minecraft_version": "1.21.9" + "date": "2025/11/23", + "minecraft_version": "1.21.10" } }, { @@ -4432,7 +4480,7 @@ { "id": "#bs.raycast:run", "kind": "function_tag", - "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/raycast.html#run-the-raycast", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/raycast.html#run", "authors": [ "Aksiome" ], @@ -4441,8 +4489,8 @@ "minecraft_version": "1.20.2" }, "updated": { - "date": "2025/08/27", - "minecraft_version": "1.21.8" + "date": "2025/11/09", + "minecraft_version": "1.21.10" } } ] diff --git a/docs/changelog/v3.2.0.md b/docs/changelog/v3.2.0.md index e3f83dbf00..40ef091c2b 100644 --- a/docs/changelog/v3.2.0.md +++ b/docs/changelog/v3.2.0.md @@ -8,6 +8,7 @@ Bookshelf is now based on **Minecraft 1.21.9/10**. - **[#403](https://github.com/mcbookshelf/bookshelf/issues/403)** - Added the `#bs.load:status` function to see loaded modules. + ### `🧱 bs.block` - 🗑️ **[#489](https://github.com/mcbookshelf/bookshelf/pull/489)** - Deprecated `play_block_sound` in favor of more granular functions (`play_break_sound`, etc.). @@ -18,6 +19,7 @@ Bookshelf is now based on **Minecraft 1.21.9/10**. - **[#489](https://github.com/mcbookshelf/bookshelf/pull/489)** - Added new block tags: `can_occlude` and `ignited_by_lava`. - **[#489](https://github.com/mcbookshelf/bookshelf/pull/489)** - Modified `emit_block_particle` to support a default `type`, aligning it with the new block sound function behavior. + ### `🎯 bs.hitbox` - 🗑️ **[#484](https://github.com/mcbookshelf/bookshelf/pull/484)** - Block tag `has_offset` has been **deprecated** and will be removed in a v4.0.0. Please use `has_shape_offset` instead. @@ -27,4 +29,15 @@ Bookshelf is now based on **Minecraft 1.21.9/10**. ### `🏃 bs.move` -- 🐛 **[#487](https://github.com/mcbookshelf/bookshelf/issues/487)** - Prevent false collision on zero-velocity axes with partial blocks like slabs +- **[#473](https://github.com/mcbookshelf/bookshelf/issues/473)** - Added custom block hitboxes and soft collisions. +- 🐛 **[#487](https://github.com/mcbookshelf/bookshelf/issues/487)** - Prevented false collisions on zero-velocity axes with partial blocks such as slabs. + + +### `🔦 bs.raycast` + +- **[#473](https://github.com/mcbookshelf/bookshelf/issues/473)** - Added custom block hitboxes and improved multi-layer piercing. + + +### `👀 bs.view` + +- 🐛 **[#498](https://github.com/mcbookshelf/bookshelf/issues/498)** - Fixed `#bs.view:at_block_placement` to match vanilla placement behavior for special blocks such as cauldrons, hoppers, composters, and scaffolding. diff --git a/docs/contribute/cli-reference.md b/docs/contribute/cli-reference.md index 3056cadcb9..98c10957b5 100644 --- a/docs/contribute/cli-reference.md +++ b/docs/contribute/cli-reference.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 📜 CLI Reference diff --git a/docs/contribute/conventions.md b/docs/contribute/conventions.md index eda36ad424..7720c412a8 100644 --- a/docs/contribute/conventions.md +++ b/docs/contribute/conventions.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 📖 Conventions diff --git a/docs/contribute/definitions.md b/docs/contribute/definitions.md index 74fffe941a..58154ebdcb 100644 --- a/docs/contribute/definitions.md +++ b/docs/contribute/definitions.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 📘 Definitions diff --git a/docs/contribute/file-format.md b/docs/contribute/file-format.md index 82644e7027..5e2feb05e9 100644 --- a/docs/contribute/file-format.md +++ b/docs/contribute/file-format.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 📄 File Format diff --git a/docs/contribute/getting-started.md b/docs/contribute/getting-started.md index 5931b7d3f9..3da2b4efec 100644 --- a/docs/contribute/getting-started.md +++ b/docs/contribute/getting-started.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 🚀 Getting Started diff --git a/docs/contribute/index.md b/docs/contribute/index.md index 3801d99b2f..88b18edc8d 100644 --- a/docs/contribute/index.md +++ b/docs/contribute/index.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 🤝 Contribute diff --git a/docs/contribute/shared-resources.md b/docs/contribute/shared-resources.md index 9219eb8609..4c8214f322 100644 --- a/docs/contribute/shared-resources.md +++ b/docs/contribute/shared-resources.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 🌐 Shared Resources diff --git a/docs/contribute/special-thanks.md b/docs/contribute/special-thanks.md index 70c72a6447..abf3097c18 100644 --- a/docs/contribute/special-thanks.md +++ b/docs/contribute/special-thanks.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # ❤️ Special Thanks diff --git a/docs/contribute/tree-structure.md b/docs/contribute/tree-structure.md index 459b0a8144..8b41e67bd7 100644 --- a/docs/contribute/tree-structure.md +++ b/docs/contribute/tree-structure.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 🌳 Tree Structure diff --git a/docs/examples/index.md b/docs/examples/index.md index 4c055d5057..4249b68da1 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 📖 Examples diff --git a/docs/index.md b/docs/index.md index 9d766d82d7..bbc9fb9a90 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true sd_hide_title: true --- diff --git a/docs/modules/hitbox.md b/docs/modules/hitbox.md index f80b9c131a..b675935a01 100644 --- a/docs/modules/hitbox.md +++ b/docs/modules/hitbox.md @@ -22,7 +22,7 @@ You can find below all functions available in this module. ```{function} #bs.hitbox:bake_entity -Bake an [entity’s hitbox](#entity-types) to improve performance when its size never changes. If the entity has passengers, they are also baked, and the base entity's hitbox is expanded to include the full bounding box of the entire stack. +Bake an [entity's hitbox](#entity-types) to improve performance when its size never changes. If the entity has passengers, they are also baked, and the base entity's hitbox is expanded to include the full bounding box of the entire stack. :Inputs: **Execution `as `**: The entity or entities whose hitbox should be baked. @@ -32,11 +32,18 @@ Bake an [entity’s hitbox](#entity-types) to improve performance when its size ``` ```{warning} -Only use baked hitboxes when you are sure the entity’s size will not change, for example: no growth (babies), no scaling, no new passengers, and no equipment that could affect size. +Only use baked hitboxes when you are sure the entity's size will not change, for example: no growth (babies), no scaling, no new passengers, and no equipment that could affect size. If the hitbox changes after baking, **it may lead to incorrect collisions or broken logic**. ``` +```{dropdown} What is a Bounding Box? +:color: info +:icon: question + +A bounding box is a simple rectangular box that surrounds an object—or part of it—to help the game figure out where it is and what it touches. For example, a set of stairs in Minecraft uses two bounding boxes: one for the lower step and one for the upper step. +``` + ```{dropdown} What is a Baked Hitbox? :color: info :icon: question @@ -492,7 +499,7 @@ Reset an [entity's hitbox](#entity-types) to its default **dynamic** form, remov **Execution `as `**: The entity or entities whose hitbox should be reset. :Outputs: - **State**: The entity’s hitbox is now dynamic again and will automatically update with scaling, growth, or other changes. + **State**: The entity's hitbox is now dynamic again and will automatically update with scaling, growth, or other changes. ``` > **Credits**: Aksiome @@ -503,7 +510,7 @@ Reset an [entity's hitbox](#entity-types) to its default **dynamic** form, remov ```{function} #bs.hitbox:set_entity -Define a [custom hitbox](#entity-types) for an entity with full control over its dimensions. This allows setting a hitbox not constrained by Minecraft’s built-in width/height system and can be used on entities that normally have no hitbox. +Define a [custom hitbox](#entity-types) for an entity with full control over its dimensions. This allows setting a hitbox not constrained by Minecraft's built-in width/height system and can be used on entities that normally have no hitbox. :Inputs: **Execution `as `**: The entity or entities whose hitbox should be set with custom dimensions. @@ -525,6 +532,12 @@ Define a [custom hitbox](#entity-types) for an entity with full control over its Custom hitboxes come with a **small performance cost**. Use them when you need precise control over shape and position, but avoid using too many of them in the same area. ``` +```{dropdown} What is a Bounding Box? +:color: info +:icon: question + +A bounding box is a simple rectangular box that surrounds an object—or part of it—to help the game figure out where it is and what it touches. For example, a set of stairs in Minecraft uses two bounding boxes: one for the lower step and one for the upper step. +``` ```{dropdown} What is a Custom Hitbox? :color: info @@ -648,7 +661,7 @@ Bookshelf provides multiple hitbox types, each suited to different use cases. Un ::::{tab-set} -:::{tab-item} 🖱 default +:::{tab-item} 🖱 Default The `default` shape defines the area where players can interact with or break the block: @@ -658,12 +671,12 @@ The `default` shape defines the area where players can interact with or break th ➔ Returned by [#bs.hitbox:get_block_shape](#get-block) ::: -:::{tab-item} 🧊 collision +:::{tab-item} 🧊 Collision The `collision` shape defines the physical boundaries of a block that entities cannot pass through. It determines where an entity will stop when moving towards the block: -- Matches the block’s solid parts and prevents entities from moving through. -- Can change dynamically depending on block state (e.g., a fence gate’s collision shape differs when open vs closed). +- Matches the block's solid parts and prevents entities from moving through. +- Can change dynamically depending on block state (e.g., a fence gate's collision shape differs when open vs closed). ➔ Returned by [#bs.hitbox:get_block_collision](#get-block) @@ -676,36 +689,36 @@ The `collision` shape defines the physical boundaries of a block that entities c ### Entities ::::{tab-set} -:::{tab-item} 🔄 dynamic +:::{tab-item} 🔄 Dynamic This is the native Minecraft hitbox, which updates automatically: - Adjusts in real time with entity changes like scaling, baby growth, equipment, or new passengers. - No setup required, this is the default behavior. -- Use when the entity’s shape is expected to change. +- Use when the entity's shape is expected to change. ➔ Restored using [#bs.hitbox:reset_entity](#reset-entity) ::: -:::{tab-item} ❄️ baked +:::{tab-item} ❄️ Baked -A snapshot of the entity’s hitbox at a specific moment: +A snapshot of the entity's hitbox at a specific moment: -- Improves performance when the entity’s size will never change. +- Improves performance when the entity's size will never change. - Includes the base entity and all passengers in one combined box. When baking a pile of passengers, the base entity bakes all passengers and sets its hitbox to encompass the entire stack. - Does not update dynamically, collisions may break if the entity changes later. ➔ Set using [#bs.hitbox:bake_entity](#bake-entity) ::: -:::{tab-item} 🛠️ custom +:::{tab-item} 🛠️ Custom A fully user-defined hitbox: - Set exact `width`, `height`, and optional `depth`. - Works on entities with no native hitbox (e.g. display entities). -- Independent from Minecraft’s internal hitbox system. -- Only applies to the base entity. When used with modules that process entity stacks, only the base entity’s hitbox is considered, passengers are ignored. +- Independent from Minecraft's internal hitbox system. +- Only applies to the base entity. When used with modules that process entity stacks, only the base entity's hitbox is considered, passengers are ignored. - Slight performance cost, avoid overuse in the same area. ➔ Set using [#bs.hitbox:set_entity](#set-entity) @@ -715,5 +728,88 @@ A fully user-defined hitbox: --- +(providers)= +## 🔌 Hitbox Providers + +A hitbox provider is a callback that returns a block's shape for consumers such as [`bs.raycast`](raycast.md) or [`bs.move`](move.md). + +A provider can return one of two forms: + +1. **A single flag** (e.g., `return 1`), telling the consumer to treat the block as a full 16×16×16 cube. +2. **An array of bounding boxes**, stored in `bs:lambda hitbox`: + ```mcfunction + {shape:[[min_x, min_y, min_z, max_x, max_y, max_z, flag], ...]} + ``` + Each bounding box uses coordinates from 0 to 16, and may include a flag (defaults to `1` if omitted). + +```{dropdown} What is a Bounding Box? +:color: info +:icon: question + +A bounding box is a simple rectangular box that surrounds an object—or part of it—to help the game figure out where it is and what it touches. For example, a set of stairs in Minecraft uses two bounding boxes: one for the lower step and one for the upper step. +``` + +```{admonition} Flags +:class: info +Flags do not have inherent meaning. They are numeric labels used by providers and consumers to classify bounding boxes. +You may use any of the following flags: `1`, `2`, `4`, or `8`. + +For example the Bookshelf built-in providers use `1` for solid and `2` for fluids. +``` + +--- + +### Available Providers + +All built-in providers include a fluid variant, where `1` represents the solid part and `2` represents the fluid part. + +::::{tab-set} + +:::{tab-item} 🖱 Default +These providers return the block's **default** shape as defined in [block types](#block-types). +- `#bs.hitbox:callback/get_block_shape` +- `#bs.hitbox:callback/get_block_shape_with_fluid` +::: + +:::{tab-item} 🧊 Collision +These providers return the block's **collision** shape as defined in [block types](#block-types). +- `#bs.hitbox:callback/get_block_collision` +- `#bs.hitbox:callback/get_block_collision_with_fluid` +::: + +:::{tab-item} 🏗 Placement +Returns the block's default shape and adds a placement-only bounding box (flag `4`) to replicate vanilla block-placement behavior for blocks such as cauldrons, composters, hoppers, and scaffolding. + +- `#bs.hitbox:callback/get_block_placement` +- `#bs.hitbox:callback/get_block_placement_with_fluid` +::: +:::: + +--- + +### Custom Providers + +A common pattern for custom providers is either to directly return a custom shape or to: + +1. Copy a built-in shape. +2. Modify it. +3. Return it. + +*Example: Defining a custom shape with a custom flag:* + +```mcfunction +# Custom shape for . You can add multiple bounding boxes, each with its own flag, if your block has a complex shape +execute if block ~ ~ ~ run return run data modify storage bs:lambda hitbox set value {shape:[[2,2,2,14,14,14,]]} + +# If the block is a full cube, return 1 +execute if block ~ ~ ~ #bs.hitbox:is_full_cube run return 1 +# Get the shape (step 1) +function #bs.hitbox:get_block_shape +# Copy and return the shape (step 3) +data modify storage bs:lambda hitbox set from storage bs:out hitbox +``` + +--- + ```{include} ../_templates/comments.md ``` diff --git a/docs/modules/index.md b/docs/modules/index.md index 9578866835..d720487df5 100644 --- a/docs/modules/index.md +++ b/docs/modules/index.md @@ -1,5 +1,5 @@ --- -html_theme.sidebar_secondary.remove: true +hide-sidebar-secondary: true --- # 🧩 Modules diff --git a/docs/modules/move.md b/docs/modules/move.md index 2a432d1630..781fff5d92 100644 --- a/docs/modules/move.md +++ b/docs/modules/move.md @@ -38,7 +38,7 @@ You can find below all functions available in this module. ```{function} #bs.move:apply_vel {scale:,with:{}} -Teleport an entity by its velocity scores while handling collisions. +Teleport an entity by its velocity scores while handling collisions. Lambda scores are only available during callback execution (`on_*`). :Inputs: **Execution `as `**: Entity to move. @@ -50,13 +50,24 @@ Teleport an entity by its velocity scores while handling collisions. - {nbt}`compound` Arguments - {nbt}`number` **scale**: Scalar applied to the output. - {nbt}`compound` **with**: Collision settings. - - {nbt}`bool` {nbt}`string` **blocks**: Whether the entity should collide with blocks (default: true). Can be a block hitbox type (`interaction` or `collision`). `true` defaults to `collision`. - - {nbt}`bool` {nbt}`string` **entities**: Whether the entity should collide with entities (default: false). Can be an entity tag. For performance, tagging entities to detect is recommended. + - {nbt}`bool` {nbt}`string` **blocks**: Whether the entity should collide with blocks (default: true). + *Can be a [hitbox provider](hitbox.md#available-providers) (e.g. `function #bs.hitbox:callback/get_block_collision`).* + - {nbt}`bool` {nbt}`string` **entities**: Whether the entity should collide with entities (default: false). + *Can be a selector tag (typically assigned via `/tag`), which is preferred for performance.* - {nbt}`string` **ignored_blocks**: Blocks to ignore (default: `#bs.hitbox:can_pass_through`). - - {nbt}`string` **ignored_entities**: Entities to ignore (default: `#bs.hitbox:intangible`). Does not apply to entities with custom hitboxes. - - {nbt}`string` **on_collision**: Command to run when a collision occurs, used to resolve the collision (default: `function #bs.move:callback/bounce`). + - {nbt}`string` **ignored_entities**: Entity type to ignore (default: `#bs.hitbox:intangible`). + *Does not apply to entities with custom hitboxes.* + - {nbt}`string` **on_collision**: Command to run when a collision occurs. + *Used to resolve the collision (default: `function #bs.move:callback/bounce`).* ::: +:Lambdas: + **Score `$move.hit_face bs.lambda`**: The face of the bounding box that was hit: 5 is east, 4 is west, 3 is south, 2 is north, 1 is top, and 0 is bottom. + + **Score `$move.hit_flag bs.lambda`**: The flag of the intersected bounding box, `-1` for entities. + + **Scores `$move.vel.[x,y,z] bs.lambda`**: The remaining velocity in canonical coordinates after collision adjustments. + :Outputs: **State**: Entity is teleported according to its velocity scores. ``` @@ -74,7 +85,7 @@ Always prefer the canonical version. Constant conversion between bases can lead If you need to "shoot" an entity in a direction, you can still set velocity as a local vector and run `#bs.move:canonical_to_local` before using `#bs.move:apply_vel`. ``` -Teleport an entity by its velocity scores, using the local reference frame, while handling collisions. +Teleport an entity by its velocity scores, using the local reference frame, while handling collisions. Lambda scores are only available during callback execution (`on_*`). :Inputs: **Execution `as `**: Entity to move. @@ -86,13 +97,23 @@ Teleport an entity by its velocity scores, using the local reference frame, whil - {nbt}`compound` Arguments - {nbt}`number` **scale**: Scalar applied to the output. - {nbt}`compound` **with**: Collision settings. - - {nbt}`bool` {nbt}`string` **blocks**: Whether the entity should collide with blocks (default: true). Can be a block hitbox type (`interaction` or `collision`). `true` defaults to `collision`. - - {nbt}`bool` {nbt}`string` **entities**: Whether the entity should collide with entities (default: false). Can be an entity tag. For performance, tagging entities to detect is recommended. + - {nbt}`bool` {nbt}`string` **blocks**: Whether the entity should collide with blocks (default: true). + *Can be a [hitbox provider](hitbox.md#available-providers) (e.g. `function #bs.hitbox:callback/get_block_collision`).* + - {nbt}`bool` {nbt}`string` **entities**: Whether the entity should collide with entities (default: false). + *Can be a selector tag (typically assigned via `/tag`), which is preferred for performance.* - {nbt}`string` **ignored_blocks**: Blocks to ignore (default: `#bs.hitbox:can_pass_through`). - - {nbt}`string` **ignored_entities**: Entities to ignore (default: `#bs.hitbox:intangible`). Does not apply to entities with custom hitboxes. + - {nbt}`string` **ignored_entities**: Entity type to ignore (default: `#bs.hitbox:intangible`). + *Does not apply to entities with custom hitboxes.* - {nbt}`string` **on_collision**: Command to run when a collision occurs, used to resolve the collision (default: `function #bs.move:callback/bounce`). ::: +:Lambdas: + **Score `$move.hit_face bs.lambda`**: The face of the bounding box that was hit. + + **Score `$move.hit_flag bs.lambda`**: The flag of the intersected bounding box, `-1` for entities. + + **Scores `$move.vel.[x,y,z] bs.lambda`**: The remaining velocity in canonical coordinates after collision adjustments. + :Outputs: **State**: Entity is teleported according to its local velocity scores. ````` @@ -100,11 +121,16 @@ Teleport an entity by its velocity scores, using the local reference frame, whil :::: ::::: -```{admonition} Hitbox Types -:class: info -Bookshelf supports multiple hitbox types for precise control. Blocks can use either `interaction` or `collision` hitboxes. Entities support three types: `dynamic`, `baked`, and `custom`. +```{dropdown} What is a Bounding Box? +:color: info +:icon: question + +A bounding box is a simple rectangular box that surrounds an object—or part of it—to help the game figure out where it is and what it touches. For example, a set of stairs in Minecraft uses two bounding boxes: one for the lower step and one for the upper step. +``` -See [Hitbox Types](hitbox.md#types) for full details. +```{admonition} Custom Hitboxes +:class: hint +Bookshelf supports multiple [hitbox types](hitbox.md#types) for precise control. Blocks can use custom [hitbox providers](hitbox.md#available-providers). Entities support three types: `dynamic`, `baked`, and `custom`. ``` *Example: Move a cube (block_display) by its velocity scores (uses an interaction as the hitbox):* @@ -248,7 +274,7 @@ This module allows you to customize collision behaviors according to your specif --- -By modifying the `on_collision` input key, you have the freedom to specify the function that triggers upon collision. However, managing the resolution yourself can be quite challenging. This is why Bookshelf provides several predefined functions: +By modifying the `on_collision` input argument, you have the freedom to specify the function that triggers upon collision. However, managing the resolution yourself can be quite challenging. This is why Bookshelf provides several predefined functions: :::{list-table} * - `#bs.move:callback/bounce` @@ -261,9 +287,14 @@ By modifying the `on_collision` input key, you have the freedom to specify the f - The entity will stop and stick to the collision surface. ::: -### How It Works? +### How It Works + +When a collision occurs, the system tracks which bounding box was hit using the velocity and the flag of that bounding box. You can modify: + +- `@s bs.vel.[x,y,z]`: the velocity that will be applied on the next tick. +- `$move.vel.[x,y,z] bs.lambda`: the remaining velocity after rolling back to the time of impact. -Upon collision, you have the freedom to update both the velocity score that will be used in the next tick `@s bs.vel.[x,y,z]` and the remaining velocity `$move.vel.[x,y,z] bs.lambda`. Since the module will attempt to continue moving based on the remaining velocity, it's crucial to avoid introducing a race condition. +To simplify the creation of custom behaviors, there's no need to handle a local velocity directly. The vector is automatically converted before and after the collision resolution. ```{admonition} Velocity Scaling :class: warning @@ -286,13 +317,38 @@ For sliding, we need to cancel the velocity on the axis that was hit and continu *`#bs.move:callback/slide`* ```mcfunction -# set a component to 0 depending on the surface that was hit +# set a component to 0 depending on the surface that was hit. execute if score $move.hit_face bs.lambda matches 4..5 store result score $move.vel.x bs.lambda run scoreboard players set @s bs.vel.x 0 execute if score $move.hit_face bs.lambda matches 0..1 store result score $move.vel.y bs.lambda run scoreboard players set @s bs.vel.y 0 execute if score $move.hit_face bs.lambda matches 2..3 store result score $move.vel.z bs.lambda run scoreboard players set @s bs.vel.z 0 ``` -To simplify the creation of these behaviors, there's no need to handle a local velocity directly. The vector is automatically converted before and after the collision resolution. If you need help with custom collisions, you can ask us on our [discord server](https://discord.gg/MkXytNjmBt)! +### Flags and Tags + +Flags and tags let you control how entities interact with multiple overlapping bounding boxes, for example, allowing movement through fluid shapes while stopping at solid shapes. + +- Each bounding box has a numeric `flag` (`1`, `2`, `4`, or `8`). +- When an entity enters a bounding box, it receives a tag `bs.move.flag.`, which prevents repeated collisions while inside bounding boxes with the same flag. The tag is removed once the entity is no longer inside any bounding box with the same flag. + +Flags are particularly useful when using a [hitbox provider](hitbox.md#available-providers) that handles fluids. For example, here's how a waterlogged stairs could respond: + +1. The stairs have two types of bounding boxes: + - **Fluid** (water) with flag `2` + - **Solid** (stairs themselves) with flag `1` + +2. The entity enters the water: + - `on_collision` is triggered. + - We can choose to preserve the velocity along the axis of collision. + - The entity receives `bs.move.flag.2`. + - While this tag is active, collisions with other water blocks or fluid shapes do nothing, so the entity keeps moving smoothly through fluids. + +3. The entity hits the solid part of the stairs: + - `on_collision` is triggered again. + - This time we reverse the velocity (bounce). + - No tag is set, so collisions with other solid shapes are processed normally. + - The entity stops or bounces off as expected, like a normal solid collision. + +If you need help with custom collisions, you can ask us on our [discord server](https://discord.gg/MkXytNjmBt)! --- diff --git a/docs/modules/raycast.md b/docs/modules/raycast.md index 057e1e1dd1..611674fac0 100644 --- a/docs/modules/raycast.md +++ b/docs/modules/raycast.md @@ -4,16 +4,21 @@ Cast rays and detect collisions with blocks or entities. -```{note} -Unlike traditional raycasts, this module uses a [voxel traversal algorithm](http://www.cse.yorku.ca/~amana/research/grid.pdf) which provides much greater precision. Additionally, thanks to the `bs.hitbox` module, it supports all different hitbox types, including both blocks and entities. -``` - ```{pull-quote} "Reality only reveals itself when it is illuminated by a ray of poetry." -- Georges Braque ``` +```{note} +This module implements a **DDA** algorithm, also known as [voxel traversal](http://www.cse.yorku.ca/~amana/research/grid.pdf). + +Instead of checking points at fixed intervals (which can miss thin shapes), the ray steps from one block boundary to the next. This ensures: +1. **Perfect Precision**: Every single block along the path is checked. +2. **Performance**: No redundant checks within the same block. +3. **Flexibility**: Works seamlessly with the `bs.hitbox` module to support complex shapes. +``` + --- ## 🔧 Functions @@ -22,11 +27,11 @@ You can find below all functions available in this module. --- -### Run the Raycast +### Run ```{function} #bs.raycast:run {with:{}} -Cast a ray from the execution position and check if it hits something. +Cast a ray from the execution position and check if it hits something. Lambda scores and storage are only available during callback execution (`on_*`). :Inputs: **Execution `at ` or `positioned rotated `**: Origin of the ray. @@ -35,23 +40,37 @@ Cast a ray from the execution position and check if it hits something. :::{treeview} - {nbt}`compound` Arguments - {nbt}`compound` **with**: Ray input data. - - {nbt}`bool` {nbt}`string` **blocks**: Whether the ray stops on blocks (default: true). Can be a block hitbox type (`interaction` or `collision`). `true` defaults to `interaction`. - - {nbt}`bool` {nbt}`string` **entities**: Whether the ray stops on entities (default: false). Can be an entity tag. For performance, tagging entities to detect is recommended. - - {nbt}`int` **piercing**: Number of blocks or entities the ray can pass through (default: 0). - - {nbt}`number` **max_distance**: Maximum ray travel distance (default: 16.0). + - {nbt}`bool` {nbt}`string` **blocks**: Whether the ray stops on blocks (default: true). + *Can be a [hitbox provider](hitbox.md#available-providers) (e.g. `function #bs.hitbox:callback/get_block_collision`).* + - {nbt}`bool` {nbt}`string` **entities**: Whether the ray stops on entities (default: false). + *Can be a selector tag (typically assigned via `/tag`), which is preferred for performance.* - {nbt}`string` **ignored_blocks**: Blocks to ignore (default: `#bs.hitbox:intangible`). - - {nbt}`string` **ignored_entities**: Entities to ignore (default: `#bs.hitbox:intangible`). Does not apply to entities with custom hitboxes. - - {nbt}`string` **on_hit_point**: Command to run at the exact point where the ray makes contact. - - {nbt}`string` **on_targeted_block**: Command to run at the block hit by the ray. - - {nbt}`string` **on_targeted_entity**: Command to run as and at the entity hit by the ray. + - {nbt}`string` **ignored_entities**: Entity type to ignore (default: `#bs.hitbox:intangible`). + *Does not apply to entities with custom hitboxes.* + - {nbt}`number` **max_distance**: Maximum ray travel distance (default: 16.0). + - {nbt}`string` **on_targeted_block**: Command to run `at` the block hit by the ray (aligned). + - {nbt}`string` **on_targeted_entity**: Command to run `as` and `at` the entity hit by the ray. + - {nbt}`string` **on_hit_point**: Command to run `at` the exact point where the ray makes contact. + *May run multiple times per block when multiple shapes are intersected.* + - {nbt}`int` {nbt}`compound` **piercing**: Number of blocks or entities the ray can pass through (default: `0`). + - {nbt}`int` **blocks**: Number of blocks to track independently from entities (default: `0`). + - {nbt}`int` **entities**: Number of entities to track independently from blocks (default: `0`). ::: :Lambdas: - **Score `$raycast.piercing bs.lambda`**: The remaining number of blocks or entities the ray can pass through before stopping. This score can be dynamically updated inside callbacks (`on_*`) to modify ray behavior. + **Score `$raycast.distance bs.lambda`**: The distance from origin (scaled ×1000). + + **Score `$raycast.hit_face bs.lambda`**: The face of the bounding box that was hit: 5 is east, 4 is west, 3 is south, 2 is north, 1 is top, and 0 is bottom. + + **Score `$raycast.hit_flag bs.lambda`**: The flag of the intersected bounding box, `-1` for entities. + + **Score `$raycast.piercing bs.lambda`**: The remaining number of blocks or entities the ray can pass through. + + **Score `$raycast.pierce_distance bs.lambda`**: The distance from previous hit point (scaled ×1000). **Storage `bs:lambda raycast`**: :::{treeview} - - {nbt}`compound` Ray lambda data, accessible only in callbacks (`on_*`) + - {nbt}`compound` Ray lambda data (deprecated will be removed in v4.0) - {nbt}`double` **distance**: The distance from the ray's origin to the impact point. - {nbt}`list` **hit_point**: The coordinates of the impact point. - {nbt}`list` **hit_normal**: The normal of the surface the ray hits. @@ -64,7 +83,7 @@ Cast a ray from the execution position and check if it hits something. **Storage `bs:out raycast`**: :::{treeview} - - {nbt}`compound` Ray output data + - {nbt}`compound` Ray output data (deprecated will be removed in v4.0) - {nbt}`double` **distance**: The distance from the ray's origin to the impact point. - {nbt}`list` **hit_point**: The coordinates of the impact point. - {nbt}`list` **hit_normal**: The normal of the surface the ray hit. @@ -73,11 +92,21 @@ Cast a ray from the execution position and check if it hits something. ::: ``` -```{admonition} Hitbox Types +```{dropdown} What is a Bounding Box? +:color: info +:icon: question + +A bounding box is a simple rectangular box that surrounds an object—or part of it—to help the game figure out where it is and what it touches. For example, a set of stairs in Minecraft uses two bounding boxes: one for the lower step and one for the upper step. +``` + +```{admonition} Callback Order :class: info -Bookshelf supports multiple hitbox types for precise control. Blocks can use either `interaction` or `collision` hitboxes. Entities support three types: `dynamic`, `baked`, and `custom`. +Callbacks `on_targeted_block` and `on_targeted_entity` are always run before `on_hit_point` to guarantee block/entity information is available before processing hit-point data. +``` -See [Hitbox Types](hitbox.md#types) for full details. +```{admonition} Custom Hitboxes +:class: hint +Bookshelf supports multiple [hitbox types](hitbox.md#types) for precise control. Blocks can use custom [hitbox providers](hitbox.md#available-providers). Entities support three types: `dynamic`, `baked`, and `custom`. ``` *Example: Cast a ray from your eyes and detect any collisions:* @@ -90,6 +119,16 @@ execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{}} data get storage bs:out raycast.hit_point ``` +*Example: Piercing multi-layer block and fluid handling:* + +```mcfunction +execute anchored eyes positioned ^ ^ ^ run function #bs.raycast:run {with:{blocks:"function #bs.hitbox:callback/get_block_shape_with_fluid",ignored_blocks:"#air",piercing:1,on_hit_point:"particle minecraft:flame ~ ~ ~ 0 0 0 0 1 force"}} +``` + +1. Callback `on_targeted_block` runs once with a `$raycast.hit_flag bs.lambda` score of `1` (solid), `2` (liquid), or `3` (both). Each unique flag is a power of 2 The `hit_flag` is the bitwise OR of all intersected shape flags ("both" being solid and liquid, `1` OR `2` = `3`). +2. Callback `on_hit_point` may run multiple times with a `$raycast.hit_flag bs.lambda` score of `1` (solid) or `2` (liquid) depending on the hit shape. +3. Piercing decremented only once per block. + > **Credits**: Aksiome --- diff --git a/docs/modules/view.md b/docs/modules/view.md index 389d06a6b4..77c387c35a 100644 --- a/docs/modules/view.md +++ b/docs/modules/view.md @@ -88,7 +88,7 @@ Run a command as the entity that is aimed by the current entity. ```mcfunction # Once (will run if you are targeting an entity) -function #bs.view:as_aimed_entity {run:"say I'm sorry, are you hitting on me?",with:{}} +function #bs.view:as_aimed_entity {run:"say I am sorry, are you hitting on me?",with:{}} ``` :::: @@ -192,7 +192,7 @@ Run a command at the precise coordinates where a block would align if placed, co ```mcfunction # Once (will run if you are targeting a block) -function #bs.view:at_block_placement {run:"setblock ~ ~ ~ minecraft:sponge"} +function #bs.view:at_block_placement {run:"setblock ~ ~ ~ minecraft:sponge",with:{}} ``` ```{dropdown} Advanced Usage diff --git a/modules/bs.raycast/data/bs.raycast/function/check/entities.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_collision.mcfunction similarity index 80% rename from modules/bs.raycast/data/bs.raycast/function/check/entities.mcfunction rename to modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_collision.mcfunction index d7a6804bc7..13260ab865 100644 --- a/modules/bs.raycast/data/bs.raycast/function/check/entities.mcfunction +++ b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_collision.mcfunction @@ -13,4 +13,6 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -$execute as @e[tag=$(entities),tag=bs.hitbox.custom,predicate=!bs.raycast:checked,distance=..255] if function bs.raycast:utils/is_near_ray run function bs.raycast:check/entity/custom +execute if block ~ ~ ~ #bs.hitbox:is_full_cube run return 1 +function #bs.hitbox:get_block_collision +data modify storage bs:lambda hitbox set from storage bs:out hitbox diff --git a/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_collision_with_fluid.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_collision_with_fluid.mcfunction new file mode 100644 index 0000000000..f4a6f385e5 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_collision_with_fluid.mcfunction @@ -0,0 +1,20 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute if block ~ ~ ~ #bs.hitbox:is_full_cube run return 1 +execute if block ~ ~ ~ #bs.hitbox:is_fluid if function bs.hitbox:callback/get_fluid_shape run return 0 +function #bs.hitbox:get_block_collision +data modify storage bs:lambda hitbox set from storage bs:out hitbox +execute if block ~ ~ ~ #bs.hitbox:is_waterloggable[waterlogged=true] run data modify storage bs:lambda hitbox.shape append value [0,0,0,16,14.2222222,16,2] diff --git a/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_placement.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_placement.mcfunction new file mode 100644 index 0000000000..4bc5d59e20 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_placement.mcfunction @@ -0,0 +1,21 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute if block ~ ~ ~ #bs.hitbox:is_full_cube run return 1 +function #bs.hitbox:get_block_shape +data modify storage bs:lambda hitbox set from storage bs:out hitbox +execute if block ~ ~ ~ #bs.hitbox:internal/placement_full run data modify storage bs:lambda hitbox.shape append value [0,0,0,16,16,16,4] +execute if block ~ ~ ~ #bs.hitbox:internal/placement_cauldrons run data modify storage bs:lambda hitbox.shape append value [0,3,0,16,16,16,4] +execute if block ~ ~ ~ minecraft:hopper run data modify storage bs:lambda hitbox.shape append value [0,10,0,16,16,16,4] diff --git a/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_placement_with_fluid.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_placement_with_fluid.mcfunction new file mode 100644 index 0000000000..ddff8a9181 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_placement_with_fluid.mcfunction @@ -0,0 +1,23 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute if block ~ ~ ~ #bs.hitbox:is_full_cube run return 1 +execute if block ~ ~ ~ #bs.hitbox:is_fluid if function bs.hitbox:callback/get_fluid_shape run return 0 +function #bs.hitbox:get_block_shape +data modify storage bs:lambda hitbox set from storage bs:out hitbox +execute if block ~ ~ ~ #bs.hitbox:is_waterloggable[waterlogged=true] run data modify storage bs:lambda hitbox.shape append value [0,0,0,16,14.2222222,16,2] +execute if block ~ ~ ~ #bs.hitbox:internal/placement_full run data modify storage bs:lambda hitbox.shape append value [0,0,0,16,16,16,4] +execute if block ~ ~ ~ #bs.hitbox:internal/placement_cauldrons run data modify storage bs:lambda hitbox.shape append value [0,3,0,16,16,16,4] +execute if block ~ ~ ~ minecraft:hopper run data modify storage bs:lambda hitbox.shape append value [0,10,0,16,16,16,4] diff --git a/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_shape.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_shape.mcfunction new file mode 100644 index 0000000000..255646180a --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_shape.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute if block ~ ~ ~ #bs.hitbox:is_full_cube run return 1 +function #bs.hitbox:get_block_shape +data modify storage bs:lambda hitbox set from storage bs:out hitbox diff --git a/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_shape_with_fluid.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_shape_with_fluid.mcfunction new file mode 100644 index 0000000000..a3130af91c --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_block_shape_with_fluid.mcfunction @@ -0,0 +1,20 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute if block ~ ~ ~ #bs.hitbox:is_full_cube run return 1 +execute if block ~ ~ ~ #bs.hitbox:is_fluid if function bs.hitbox:callback/get_fluid_shape run return 0 +function #bs.hitbox:get_block_shape +data modify storage bs:lambda hitbox set from storage bs:out hitbox +execute if block ~ ~ ~ #bs.hitbox:is_waterloggable[waterlogged=true] run data modify storage bs:lambda hitbox.shape append value [0,0,0,16,14.2222222,16,2] diff --git a/modules/bs.hitbox/data/bs.hitbox/function/callback/get_fluid_shape.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_fluid_shape.mcfunction new file mode 100644 index 0000000000..fde5a701e2 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/function/callback/get_fluid_shape.mcfunction @@ -0,0 +1,23 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute if block ~ ~ ~ #bs.hitbox:is_fluid[level=7] run return run data modify storage bs:lambda hitbox set value {shape:[[0,0,0,16,1.7777777,16,2]]} +execute if block ~ ~ ~ #bs.hitbox:is_fluid[level=6] run return run data modify storage bs:lambda hitbox set value {shape:[[0,0,0,16,3.5555555,16,2]]} +execute if block ~ ~ ~ #bs.hitbox:is_fluid[level=5] run return run data modify storage bs:lambda hitbox set value {shape:[[0,0,0,16,5.3333333,16,2]]} +execute if block ~ ~ ~ #bs.hitbox:is_fluid[level=4] run return run data modify storage bs:lambda hitbox set value {shape:[[0,0,0,16,7.1111111,16,2]]} +execute if block ~ ~ ~ #bs.hitbox:is_fluid[level=3] run return run data modify storage bs:lambda hitbox set value {shape:[[0,0,0,16,8.8888888,16,2]]} +execute if block ~ ~ ~ #bs.hitbox:is_fluid[level=2] run return run data modify storage bs:lambda hitbox set value {shape:[[0,0,0,16,10.6666666,16,2]]} +execute if block ~ ~ ~ #bs.hitbox:is_fluid[level=1] run return run data modify storage bs:lambda hitbox set value {shape:[[0,0,0,16,12.4444444,16,2]]} +data modify storage bs:lambda hitbox set value {shape:[[0,0,0,16,14.2222222,16,2]]} diff --git a/modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block.mcfunction index 9d0060f33e..0cbcb20011 100644 --- a/modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block.mcfunction +++ b/modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block.mcfunction @@ -30,9 +30,9 @@ function #bs.log:warn { \ } data modify storage bs:out hitbox set value {} -loot replace entity B5-0-0-0-3 contents loot bs.hitbox:block/default +loot replace entity B5-0-0-0-3 contents loot bs.hitbox:block/get_collision data modify storage bs:out hitbox.interaction_shape set from entity B5-0-0-0-3 item.components."minecraft:custom_data".shape -loot replace entity B5-0-0-0-3 contents loot bs.hitbox:block/collision +loot replace entity B5-0-0-0-3 contents loot bs.hitbox:block/get_shape data modify storage bs:out hitbox.collision_shape set from entity B5-0-0-0-3 item.components."minecraft:custom_data".shape execute if block ~ ~ ~ #bs.hitbox:has_shape_offset summon minecraft:marker run function bs.hitbox:get_block/offset/get diff --git a/modules/bs.hitbox/data/bs.hitbox/function/get_block/default.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block_collision.mcfunction similarity index 92% rename from modules/bs.hitbox/data/bs.hitbox/function/get_block/default.mcfunction rename to modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block_collision.mcfunction index 7ce8cf0dfd..3b77036f81 100644 --- a/modules/bs.hitbox/data/bs.hitbox/function/get_block/default.mcfunction +++ b/modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block_collision.mcfunction @@ -13,6 +13,6 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -loot replace entity B5-0-0-0-3 contents loot bs.hitbox:block/default +loot replace entity B5-0-0-0-3 contents loot bs.hitbox:block/get_collision data modify storage bs:out hitbox set from entity B5-0-0-0-3 item.components."minecraft:custom_data" execute if block ~ ~ ~ #bs.hitbox:has_shape_offset summon minecraft:marker run function bs.hitbox:get_block/offset/get diff --git a/modules/bs.hitbox/data/bs.hitbox/function/get_block/collision.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block_shape.mcfunction similarity index 93% rename from modules/bs.hitbox/data/bs.hitbox/function/get_block/collision.mcfunction rename to modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block_shape.mcfunction index 35e0d89b2d..7ce82b5807 100644 --- a/modules/bs.hitbox/data/bs.hitbox/function/get_block/collision.mcfunction +++ b/modules/bs.hitbox/data/bs.hitbox/function/get_block/get_block_shape.mcfunction @@ -13,6 +13,6 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -loot replace entity B5-0-0-0-3 contents loot bs.hitbox:block/collision +loot replace entity B5-0-0-0-3 contents loot bs.hitbox:block/get_shape data modify storage bs:out hitbox set from entity B5-0-0-0-3 item.components."minecraft:custom_data" execute if block ~ ~ ~ #bs.hitbox:has_shape_offset summon minecraft:marker run function bs.hitbox:get_block/offset/get diff --git a/modules/bs.hitbox/data/bs.hitbox/function/get_entity/get_entity.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/get_entity/get_entity.mcfunction index 025678255e..52efe1e373 100644 --- a/modules/bs.hitbox/data/bs.hitbox/function/get_entity/get_entity.mcfunction +++ b/modules/bs.hitbox/data/bs.hitbox/function/get_entity/get_entity.mcfunction @@ -16,13 +16,13 @@ execute if entity @s[scores={bs.width=0..,bs.height=0..,bs.depth=0..}] run return run function bs.hitbox:get_entity/get_custom scoreboard players set #i bs.ctx 0 -execute if entity @s[type=#bs.hitbox:size/group_1] run scoreboard players add #i bs.ctx 1 -execute if entity @s[type=#bs.hitbox:size/group_2] run scoreboard players add #i bs.ctx 2 -execute if entity @s[type=#bs.hitbox:size/group_4] run scoreboard players add #i bs.ctx 4 -execute if entity @s[type=#bs.hitbox:size/group_8] run scoreboard players add #i bs.ctx 8 -execute if entity @s[type=#bs.hitbox:size/group_16] run scoreboard players add #i bs.ctx 16 -execute if entity @s[type=#bs.hitbox:size/group_32] run scoreboard players add #i bs.ctx 32 -execute if entity @s[type=#bs.hitbox:size/group_64] run scoreboard players add #i bs.ctx 64 +execute if entity @s[type=#bs.hitbox:internal/group_1] run scoreboard players add #i bs.ctx 1 +execute if entity @s[type=#bs.hitbox:internal/group_2] run scoreboard players add #i bs.ctx 2 +execute if entity @s[type=#bs.hitbox:internal/group_4] run scoreboard players add #i bs.ctx 4 +execute if entity @s[type=#bs.hitbox:internal/group_8] run scoreboard players add #i bs.ctx 8 +execute if entity @s[type=#bs.hitbox:internal/group_16] run scoreboard players add #i bs.ctx 16 +execute if entity @s[type=#bs.hitbox:internal/group_32] run scoreboard players add #i bs.ctx 32 +execute if entity @s[type=#bs.hitbox:internal/group_64] run scoreboard players add #i bs.ctx 64 execute store result storage bs:ctx y short 1 run scoreboard players get #i bs.ctx function bs.hitbox:get_entity/dispatch with storage bs:ctx diff --git a/modules/bs.hitbox/data/bs.hitbox/function/get_entity/registry/74.mcfunction b/modules/bs.hitbox/data/bs.hitbox/function/get_entity/registry/74.mcfunction new file mode 100644 index 0000000000..2ad03c84cd --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/function/get_entity/registry/74.mcfunction @@ -0,0 +1,21 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# mannequin group +data modify storage bs:ctx _ set from entity @s +execute if data storage bs:ctx _{pose:"standing"} run return run data modify storage bs:out hitbox set value {width:0.6,height:1.8} +execute if data storage bs:ctx _{pose:"crouching"} run return run data modify storage bs:out hitbox set value {width:0.6,height:1.5} +execute if data storage bs:ctx _{pose:"sleeping"} run return run data modify storage bs:out hitbox set value {width:0.2,height:0.2} +data modify storage bs:out hitbox set value {width:0.6,height:0.6} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/block/internal/placement_cauldrons.json b/modules/bs.hitbox/data/bs.hitbox/tags/block/internal/placement_cauldrons.json new file mode 100644 index 0000000000..3881eb9366 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/block/internal/placement_cauldrons.json @@ -0,0 +1,8 @@ +{ + "values": [ + "minecraft:cauldron", + "minecraft:lava_cauldron", + "minecraft:powder_snow_cauldron", + "minecraft:water_cauldron" + ] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/block/internal/placement_full.json b/modules/bs.hitbox/data/bs.hitbox/tags/block/internal/placement_full.json new file mode 100644 index 0000000000..3c25ac5922 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/block/internal/placement_full.json @@ -0,0 +1,6 @@ +{ + "values": [ + "minecraft:composter", + "minecraft:scaffolding" + ] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/block/is_fluid.json b/modules/bs.hitbox/data/bs.hitbox/tags/block/is_fluid.json new file mode 100644 index 0000000000..f80ba160a6 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/block/is_fluid.json @@ -0,0 +1,22 @@ +{ + "__bookshelf__": { + "feature": true, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#blocks", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + "values": [ + "minecraft:bubble_column", + "minecraft:lava", + "minecraft:water" + ] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/block/is_waterloggable.json b/modules/bs.hitbox/data/bs.hitbox/tags/block/is_waterloggable.json new file mode 100644 index 0000000000..91cdd8a8ea --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/block/is_waterloggable.json @@ -0,0 +1,18 @@ +{ + "__bookshelf__": { + "feature": true, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#blocks", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + "values": [] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/block/none.json b/modules/bs.hitbox/data/bs.hitbox/tags/block/none.json new file mode 100644 index 0000000000..91cdd8a8ea --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/block/none.json @@ -0,0 +1,18 @@ +{ + "__bookshelf__": { + "feature": true, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#blocks", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + "values": [] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/arrow_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/arrow_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/arrow_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/arrow_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/bat_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/bat_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/bat_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/bat_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/boat.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/boat.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/boat.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/boat.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/cat_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/cat_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/cat_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/cat_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/cow_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/cow_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/cow_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/cow_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/falling_block_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/falling_block_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/falling_block_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/falling_block_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/ghast_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/ghast_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/ghast_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/ghast_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_1.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_1.json similarity index 62% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_1.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_1.json index b2c72bb295..1b1dfb86ee 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_1.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_1.json @@ -4,28 +4,28 @@ "minecraft:armor_stand", "minecraft:axolotl", "minecraft:bee", - "#bs.hitbox:size/boat", - "#bs.hitbox:size/cat_like", + "#bs.hitbox:internal/boat", + "#bs.hitbox:internal/cat_like", "minecraft:chicken", - "#bs.hitbox:size/cow_like", + "#bs.hitbox:internal/cow_like", "minecraft:dolphin", "minecraft:elder_guardian", "minecraft:ender_dragon", - "#bs.hitbox:size/falling_block_like", - "#bs.hitbox:size/ghast_like", + "#bs.hitbox:internal/falling_block_like", + "#bs.hitbox:internal/ghast_like", "minecraft:evoker_fangs", - "#bs.hitbox:size/hoglin", + "#bs.hitbox:internal/hoglin", "minecraft:interaction", - "#bs.hitbox:size/item_like", + "#bs.hitbox:internal/item_like", "minecraft:leash_knot", - "#bs.hitbox:size/minecart", + "#bs.hitbox:internal/minecart", "minecraft:panda", "minecraft:pig", "minecraft:pufferfish", "minecraft:ravager", "minecraft:sheep", - "#bs.hitbox:size/silverfish_like", - "#bs.hitbox:size/slime_like", + "#bs.hitbox:internal/silverfish_like", + "#bs.hitbox:internal/slime_like", "minecraft:sniffer", "minecraft:spider", "minecraft:strider", @@ -33,7 +33,7 @@ "minecraft:vex", "minecraft:wither", "minecraft:breeze", - "#bs.hitbox:size/zombie_like", + "#bs.hitbox:internal/zombie_like", "minecraft:villager", "minecraft:armadillo", "minecraft:copper_golem" diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_16.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_16.json similarity index 63% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_16.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_16.json index 2f21eedbb4..96c5fe0a77 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_16.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_16.json @@ -7,20 +7,20 @@ "minecraft:end_crystal", "minecraft:ender_dragon", "minecraft:enderman", - "#bs.hitbox:size/falling_block_like", + "#bs.hitbox:internal/falling_block_like", "minecraft:frog", - "#bs.hitbox:size/ghast_like", + "#bs.hitbox:internal/ghast_like", "minecraft:giant", "minecraft:evoker_fangs", "minecraft:guardian", - "#bs.hitbox:size/hoglin", - "#bs.hitbox:size/horse_like", + "#bs.hitbox:internal/hoglin", + "#bs.hitbox:internal/horse_like", "minecraft:interaction", - "#bs.hitbox:size/shulker_like", - "#bs.hitbox:size/silverfish_like", - "#bs.hitbox:size/skeleton", - "#bs.hitbox:size/slime_like", - "#bs.hitbox:size/small_fireball_like", + "#bs.hitbox:internal/shulker_like", + "#bs.hitbox:internal/silverfish_like", + "#bs.hitbox:internal/skeleton", + "#bs.hitbox:internal/slime_like", + "#bs.hitbox:internal/small_fireball_like", "minecraft:sniffer", "minecraft:snow_golem", "minecraft:spider", diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_2.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_2.json similarity index 63% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_2.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_2.json index 2843c3c274..19ef28f8e8 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_2.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_2.json @@ -2,21 +2,21 @@ "values": [ "minecraft:area_effect_cloud", "minecraft:armor_stand", - "#bs.hitbox:size/bat_like", + "#bs.hitbox:internal/bat_like", "minecraft:bee", "minecraft:camel", - "#bs.hitbox:size/cat_like", + "#bs.hitbox:internal/cat_like", "minecraft:cod", - "#bs.hitbox:size/cow_like", + "#bs.hitbox:internal/cow_like", "minecraft:donkey", "minecraft:elder_guardian", "minecraft:enderman", - "#bs.hitbox:size/falling_block_like", + "#bs.hitbox:internal/falling_block_like", "minecraft:giant", "minecraft:evoker_fangs", - "#bs.hitbox:size/horse_like", + "#bs.hitbox:internal/horse_like", "minecraft:interaction", - "#bs.hitbox:size/item_frame", + "#bs.hitbox:internal/item_frame", "minecraft:leash_knot", "minecraft:painting", "minecraft:panda", @@ -24,8 +24,8 @@ "minecraft:pufferfish", "minecraft:salmon", "minecraft:sheep", - "#bs.hitbox:size/skeleton", - "#bs.hitbox:size/slime_like", + "#bs.hitbox:internal/skeleton", + "#bs.hitbox:internal/slime_like", "minecraft:snow_golem", "minecraft:spider", "minecraft:tadpole", @@ -33,8 +33,9 @@ "minecraft:warden", "minecraft:wither", "minecraft:wolf", - "#bs.hitbox:size/zombie_like", + "#bs.hitbox:internal/zombie_like", "minecraft:goat", - "minecraft:armadillo" + "minecraft:armadillo", + "minecraft:mannequin" ] } diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_32.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_32.json similarity index 63% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_32.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_32.json index 82519ac6b5..d7ff20fae8 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_32.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_32.json @@ -1,11 +1,11 @@ { "values": [ "minecraft:iron_golem", - "#bs.hitbox:size/item_like", - "#bs.hitbox:size/item_frame", + "#bs.hitbox:internal/item_like", + "#bs.hitbox:internal/item_frame", "minecraft:leash_knot", - "#bs.hitbox:size/llama", - "#bs.hitbox:size/minecart", + "#bs.hitbox:internal/llama", + "#bs.hitbox:internal/minecart", "minecraft:painting", "minecraft:panda", "minecraft:phantom", @@ -16,11 +16,11 @@ "minecraft:ravager", "minecraft:salmon", "minecraft:sheep", - "#bs.hitbox:size/shulker_like", - "#bs.hitbox:size/silverfish_like", - "#bs.hitbox:size/skeleton", - "#bs.hitbox:size/slime_like", - "#bs.hitbox:size/small_fireball_like", + "#bs.hitbox:internal/shulker_like", + "#bs.hitbox:internal/silverfish_like", + "#bs.hitbox:internal/skeleton", + "#bs.hitbox:internal/slime_like", + "#bs.hitbox:internal/small_fireball_like", "minecraft:sniffer", "minecraft:snow_golem", "minecraft:spider", diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_4.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_4.json similarity index 66% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_4.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_4.json index 3f296749d1..c67f2a0158 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_4.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_4.json @@ -1,30 +1,30 @@ { "values": [ - "#bs.hitbox:size/arrow_like", + "#bs.hitbox:internal/arrow_like", "minecraft:axolotl", - "#bs.hitbox:size/bat_like", + "#bs.hitbox:internal/bat_like", "minecraft:bee", "minecraft:cave_spider", "minecraft:chicken", "minecraft:cod", - "#bs.hitbox:size/cow_like", + "#bs.hitbox:internal/cow_like", "minecraft:end_crystal", "minecraft:ender_dragon", "minecraft:enderman", - "#bs.hitbox:size/falling_block_like", + "#bs.hitbox:internal/falling_block_like", "minecraft:guardian", - "#bs.hitbox:size/hoglin", - "#bs.hitbox:size/horse_like", + "#bs.hitbox:internal/hoglin", + "#bs.hitbox:internal/horse_like", "minecraft:interaction", - "#bs.hitbox:size/llama", - "#bs.hitbox:size/minecart", + "#bs.hitbox:internal/llama", + "#bs.hitbox:internal/minecart", "minecraft:painting", "minecraft:panda", "minecraft:rabbit", "minecraft:ravager", "minecraft:salmon", "minecraft:sheep", - "#bs.hitbox:size/small_fireball_like", + "#bs.hitbox:internal/small_fireball_like", "minecraft:sniffer", "minecraft:snow_golem", "minecraft:spider", @@ -33,7 +33,6 @@ "minecraft:warden", "minecraft:wither", "minecraft:player", - "minecraft:mannequin", "minecraft:goat", "minecraft:villager", "minecraft:armadillo" diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_64.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_64.json similarity index 70% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_64.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_64.json index 794388a241..654cabd94c 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_64.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_64.json @@ -3,13 +3,13 @@ "minecraft:wither_skeleton", "minecraft:breeze", "minecraft:wolf", - "#bs.hitbox:size/zombie_like", + "#bs.hitbox:internal/zombie_like", "minecraft:player", - "minecraft:mannequin", "minecraft:goat", "minecraft:villager", "minecraft:armadillo", "minecraft:creaking", - "minecraft:copper_golem" + "minecraft:copper_golem", + "minecraft:mannequin" ] } diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_8.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_8.json similarity index 71% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_8.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_8.json index 840c4166a3..06cd55314d 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/group_8.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/group_8.json @@ -1,20 +1,20 @@ { "values": [ "minecraft:blaze", - "#bs.hitbox:size/boat", + "#bs.hitbox:internal/boat", "minecraft:camel", - "#bs.hitbox:size/cat_like", + "#bs.hitbox:internal/cat_like", "minecraft:cave_spider", "minecraft:chicken", "minecraft:cod", - "#bs.hitbox:size/cow_like", + "#bs.hitbox:internal/cow_like", "minecraft:frog", - "#bs.hitbox:size/ghast_like", + "#bs.hitbox:internal/ghast_like", "minecraft:giant", "minecraft:evoker_fangs", "minecraft:guardian", - "#bs.hitbox:size/hoglin", - "#bs.hitbox:size/horse_like", + "#bs.hitbox:internal/hoglin", + "#bs.hitbox:internal/horse_like", "minecraft:interaction", "minecraft:phantom", "minecraft:pig", @@ -33,6 +33,7 @@ "minecraft:warden", "minecraft:wither", "minecraft:creaking", - "minecraft:copper_golem" + "minecraft:copper_golem", + "minecraft:mannequin" ] } diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/hoglin.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/hoglin.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/hoglin.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/hoglin.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/horse_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/horse_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/horse_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/horse_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/item_frame.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/item_frame.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/item_frame.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/item_frame.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/item_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/item_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/item_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/item_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/llama.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/llama.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/llama.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/llama.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/minecart.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/minecart.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/minecart.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/minecart.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/shulker_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/shulker_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/shulker_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/shulker_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/silverfish_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/silverfish_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/silverfish_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/silverfish_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/skeleton.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/skeleton.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/skeleton.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/skeleton.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/slime_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/slime_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/slime_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/slime_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/small_fireball_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/small_fireball_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/small_fireball_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/small_fireball_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/zombie_like.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/zombie_like.json similarity index 100% rename from modules/bs.hitbox/data/bs.hitbox/tags/entity_type/size/zombie_like.json rename to modules/bs.hitbox/data/bs.hitbox/tags/entity_type/internal/zombie_like.json diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/is_shaped.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/is_shaped.json index f314fed28a..59c38bbfc0 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/is_shaped.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/is_shaped.json @@ -15,7 +15,7 @@ } }, "values": [ - "#bs.hitbox:size/item_frame", + "#bs.hitbox:internal/item_frame", "minecraft:painting" ] } diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/is_sized.json b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/is_sized.json index 08d21ab1ac..8d8042df03 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/is_sized.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/entity_type/is_sized.json @@ -15,24 +15,24 @@ } }, "values": [ - "#bs.hitbox:size/arrow_like", - "#bs.hitbox:size/bat_like", - "#bs.hitbox:size/boat", - "#bs.hitbox:size/cat_like", - "#bs.hitbox:size/cow_like", - "#bs.hitbox:size/falling_block_like", - "#bs.hitbox:size/ghast_like", - "#bs.hitbox:size/hoglin", - "#bs.hitbox:size/horse_like", - "#bs.hitbox:size/item_like", - "#bs.hitbox:size/llama", - "#bs.hitbox:size/minecart", - "#bs.hitbox:size/shulker_like", - "#bs.hitbox:size/silverfish_like", - "#bs.hitbox:size/skeleton", - "#bs.hitbox:size/slime_like", - "#bs.hitbox:size/small_fireball_like", - "#bs.hitbox:size/zombie_like", + "#bs.hitbox:internal/arrow_like", + "#bs.hitbox:internal/bat_like", + "#bs.hitbox:internal/boat", + "#bs.hitbox:internal/cat_like", + "#bs.hitbox:internal/cow_like", + "#bs.hitbox:internal/falling_block_like", + "#bs.hitbox:internal/ghast_like", + "#bs.hitbox:internal/hoglin", + "#bs.hitbox:internal/horse_like", + "#bs.hitbox:internal/item_like", + "#bs.hitbox:internal/llama", + "#bs.hitbox:internal/minecart", + "#bs.hitbox:internal/shulker_like", + "#bs.hitbox:internal/silverfish_like", + "#bs.hitbox:internal/skeleton", + "#bs.hitbox:internal/slime_like", + "#bs.hitbox:internal/small_fireball_like", + "#bs.hitbox:internal/zombie_like", "minecraft:allay", "minecraft:area_effect_cloud", "minecraft:armadillo", diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_collision.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_collision.json new file mode 100644 index 0000000000..00e1fd4eae --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_collision.json @@ -0,0 +1,20 @@ +{ + "__bookshelf__": { + "feature": false, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#providers", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/10/07", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + "values": [ + "bs.hitbox:callback/get_block_collision" + ] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_collision_with_fluid.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_collision_with_fluid.json new file mode 100644 index 0000000000..244ef975af --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_collision_with_fluid.json @@ -0,0 +1,20 @@ +{ + "__bookshelf__": { + "feature": false, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#providers", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/10/07", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + "values": [ + "bs.hitbox:callback/get_block_collision_with_fluid" + ] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_placement.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_placement.json new file mode 100644 index 0000000000..60fc9ef63c --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_placement.json @@ -0,0 +1,20 @@ +{ + "__bookshelf__": { + "feature": false, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#providers", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + "values": [ + "bs.hitbox:callback/get_block_placement" + ] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_placement_with_fluid.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_placement_with_fluid.json new file mode 100644 index 0000000000..52653def42 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_placement_with_fluid.json @@ -0,0 +1,20 @@ +{ + "__bookshelf__": { + "feature": false, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#providers", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + "values": [ + "bs.hitbox:callback/get_block_placement_with_fluid" + ] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_shape.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_shape.json new file mode 100644 index 0000000000..7ce7f63073 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_shape.json @@ -0,0 +1,20 @@ +{ + "__bookshelf__": { + "feature": false, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#providers", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/10/07", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + "values": [ + "bs.hitbox:callback/get_block_shape" + ] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_shape_with_fluid.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_shape_with_fluid.json new file mode 100644 index 0000000000..56ea238330 --- /dev/null +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/callback/get_block_shape_with_fluid.json @@ -0,0 +1,20 @@ +{ + "__bookshelf__": { + "feature": false, + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#providers", + "authors": [ + "Aksiome" + ], + "created": { + "date": "2025/10/07", + "minecraft_version": "1.21.10" + }, + "updated": { + "date": "2025/11/11", + "minecraft_version": "1.21.10" + } + }, + "values": [ + "bs.hitbox:callback/get_block_shape_with_fluid" + ] +} diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block.json index b579a5feaa..82cc69acb0 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block.json @@ -2,7 +2,7 @@ "__bookshelf__": { "feature": true, "deprecated": true, - "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#get", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#get-block", "authors": [ "Aksiome" ], diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block_collision.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block_collision.json index 14b3bba345..3c124619c5 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block_collision.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block_collision.json @@ -15,6 +15,6 @@ } }, "values": [ - "bs.hitbox:get_block/collision" + "bs.hitbox:get_block/get_block_collision" ] } diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block_shape.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block_shape.json index b39f47bcd2..1f91e9f5f0 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block_shape.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/get_block_shape.json @@ -15,6 +15,6 @@ } }, "values": [ - "bs.hitbox:get_block/default" + "bs.hitbox:get_block/get_block_shape" ] } diff --git a/modules/bs.hitbox/data/bs.hitbox/tags/function/get_entity.json b/modules/bs.hitbox/data/bs.hitbox/tags/function/get_entity.json index ddb68b6da0..bd0504c986 100644 --- a/modules/bs.hitbox/data/bs.hitbox/tags/function/get_entity.json +++ b/modules/bs.hitbox/data/bs.hitbox/tags/function/get_entity.json @@ -1,7 +1,7 @@ { "__bookshelf__": { "feature": true, - "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#get", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/hitbox.html#get-entity", "authors": [ "Aksiome" ], diff --git a/modules/bs.hitbox/gen_hitbox.py b/modules/bs.hitbox/gen_hitbox.py index 64acb9af0a..3fd6b4e655 100644 --- a/modules/bs.hitbox/gen_hitbox.py +++ b/modules/bs.hitbox/gen_hitbox.py @@ -6,17 +6,23 @@ from bookshelf.models import Block, StatePredicate, StateValue, VoxelShape from bookshelf.services import minecraft +CUBE = ((0.0, 0.0, 0.0, 16.0, 16.0, 16.0),) +INTANGIBLE = [ + "minecraft:light", + "minecraft:structure_void", +] + def beet_default(ctx: Context) -> None: """Generate files used by the bs.hitbox module.""" namespace = ctx.directory.name blocks = minecraft.get_blocks(ctx, MC_VERSIONS[-1]) - groups = {"default": defaultdict(list), "collision": defaultdict(list)} + groups = {"shape": defaultdict(list), "collision": defaultdict(list)} seen = set() for block in blocks: - groups["default"][block.shape].append(block) + groups["shape"][block.shape].append(block) groups["collision"][block.collision_shape].append(block) for shape in (block.shape, block.collision_shape): @@ -27,23 +33,19 @@ def beet_default(ctx: Context) -> None: for name, mapping in groups.items(): loot_table = make_shape_loot_table(mapping, f"{namespace}:block") - ctx.generate(f"{namespace}:block/{name}", render=loot_table) + ctx.generate(f"{namespace}:block/get_{name}", render=loot_table) - for name, predicate, extras in [ - ("has_shape_offset", lambda b: b.has_shape_offset, []), - ("has_visual_offset", lambda b: b.has_visual_offset, []), - ("can_pass_through", lambda b: not b.collision_shape, []), - ("intangible", lambda b: not b.shape, [ - "minecraft:light", - "minecraft:structure_void", - ]), - ("is_full_cube", lambda block: ( - block.shape == ((0.0, 0.0, 0.0, 16.0, 16.0, 16.0),) - and block.collision_shape == ((0.0, 0.0, 0.0, 16.0, 16.0, 16.0),) - ), []), + for name, predicate in [ + ("has_shape_offset", lambda b: b.has_shape_offset), + ("has_visual_offset", lambda b: b.has_visual_offset), + ("can_pass_through", lambda b: not b.collision_shape), + ("intangible", lambda b: b.type in INTANGIBLE or not b.shape), + ("is_full_cube", lambda b: b.shape == CUBE and b.collision_shape == CUBE), + ("is_waterloggable", lambda b: + any(p.name == "waterlogged" for p in b.properties)), ]: if tag := ctx.data.block_tags.get(f"{namespace}:{name}"): - tag.merge(minecraft.make_block_tag(blocks, predicate, extras)) + tag.merge(minecraft.make_block_tag(blocks, predicate)) def make_shape_loot_table( diff --git a/modules/bs.move/data/bs.move/function/collision/check/aabb.mcfunction b/modules/bs.move/data/bs.move/function/collision/check/aabb.mcfunction index 5783593b54..43d704c6dd 100644 --- a/modules/bs.move/data/bs.move/function/collision/check/aabb.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/check/aabb.mcfunction @@ -45,7 +45,4 @@ scoreboard players operation #i bs.ctx < #j bs.ctx scoreboard players operation #i bs.ctx < #k bs.ctx # check for valid intersection: near ≤ far and within ray bounds -execute if score #i bs.ctx matches 0.. \ - if score #x bs.ctx <= #i bs.ctx \ - if score #move.toi bs.data > #x bs.ctx \ - run function bs.move:collision/collide +execute if score #i bs.ctx matches 0.. if score #x bs.ctx <= #i bs.ctx run function bs.move:collision/collide with storage bs:ctx diff --git a/modules/bs.move/data/bs.move/function/collision/check/kind.mcfunction b/modules/bs.move/data/bs.move/function/collision/check/any.mcfunction similarity index 100% rename from modules/bs.move/data/bs.move/function/collision/check/kind.mcfunction rename to modules/bs.move/data/bs.move/function/collision/check/any.mcfunction index 74e29f0151..2f1ba4defb 100644 --- a/modules/bs.move/data/bs.move/function/collision/check/kind.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/check/any.mcfunction @@ -13,5 +13,5 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -execute unless data storage bs:data move{entities:0b} run function bs.move:collision/check/entities with storage bs:data move execute unless data storage bs:data move{blocks:0b} run function bs.move:collision/check/blocks +execute unless data storage bs:data move{entities:0b} run function bs.move:collision/check/entities with storage bs:data move diff --git a/modules/bs.move/data/bs.move/function/collision/check/block/any.mcfunction b/modules/bs.move/data/bs.move/function/collision/check/block/any.mcfunction index 12f6362a40..b9e1f47721 100644 --- a/modules/bs.move/data/bs.move/function/collision/check/block/any.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/check/block/any.mcfunction @@ -14,14 +14,16 @@ # ------------------------------------------------------------------------------------------------------------ # if the block is a full cube, check collision using a fixed 1×1×1 AABB -execute if block ~ ~ ~ #bs.hitbox:is_full_cube run return run function bs.move:collision/check/block/cube +data remove storage bs:lambda hitbox +scoreboard players set #move.hit_flag bs.data 0 +$execute store result storage bs:ctx y int 1 store result score #move.hit_flag bs.data run $(blocks) +execute if score #move.hit_flag bs.data matches 1.. unless data storage bs:lambda hitbox run return run function bs.move:collision/check/block/cube with storage bs:ctx # otherwise, check collision against the block shape -$$(blocks) -execute unless data storage bs:out hitbox.shape run return 0 -data modify storage bs:ctx _ set from storage bs:out hitbox.shape -execute store result score #p bs.ctx run data get storage bs:out hitbox.offset.x 10000000 -execute store result score #q bs.ctx run data get storage bs:out hitbox.offset.z 10000000 +execute store result score #p bs.ctx run data get storage bs:lambda hitbox.offset.x 10000000 +execute store result score #q bs.ctx run data get storage bs:lambda hitbox.offset.z 10000000 scoreboard players operation #p bs.ctx += #move.x bs.data scoreboard players operation #q bs.ctx += #move.z bs.data -function bs.move:collision/check/block/shape +execute store result score #move.hit_flag bs.data store result storage bs:ctx y int 1 run data get storage bs:lambda hitbox.shape[-1][6] +execute if score #move.hit_flag bs.data matches 0 store result storage bs:ctx y int 1 run scoreboard players set #move.hit_flag bs.data 1 +execute if data storage bs:lambda hitbox.shape[-1] run function bs.move:collision/check/block/shape with storage bs:ctx diff --git a/modules/bs.move/data/bs.move/function/collision/check/block/cube.mcfunction b/modules/bs.move/data/bs.move/function/collision/check/block/cube.mcfunction index 6746d50a96..a04a64de0f 100644 --- a/modules/bs.move/data/bs.move/function/collision/check/block/cube.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/check/block/cube.mcfunction @@ -13,6 +13,8 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ +$execute if entity @s[tag=bs.move.flag.$(y)] run return 0 + # get cube bounding box coordinates execute store result score #i bs.ctx run scoreboard players operation #x bs.ctx = #move.x bs.data execute store result score #j bs.ctx run scoreboard players operation #y bs.ctx = #move.y bs.data diff --git a/modules/bs.move/data/bs.move/function/collision/check/block/next_shape.mcfunction b/modules/bs.move/data/bs.move/function/collision/check/block/next_shape.mcfunction new file mode 100644 index 0000000000..8f2f9dc408 --- /dev/null +++ b/modules/bs.move/data/bs.move/function/collision/check/block/next_shape.mcfunction @@ -0,0 +1,19 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +data remove storage bs:lambda hitbox.shape[-1] +execute store result score #move.hit_flag bs.data store result storage bs:ctx y int 1 run data get storage bs:lambda hitbox.shape[-1][6] +execute if score #move.hit_flag bs.data matches 0 store result storage bs:ctx y int 1 run scoreboard players set #move.hit_flag bs.data 1 +execute if data storage bs:lambda hitbox.shape[-1] run function bs.move:collision/check/block/shape with storage bs:ctx diff --git a/modules/bs.move/data/bs.move/function/collision/check/block/shape.mcfunction b/modules/bs.move/data/bs.move/function/collision/check/block/shape.mcfunction index 2ca4ae390f..874b955bca 100644 --- a/modules/bs.move/data/bs.move/function/collision/check/block/shape.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/check/block/shape.mcfunction @@ -13,14 +13,16 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ +$execute if entity @s[tag=bs.move.flag.$(y)] run return run function bs.move:collision/check/block/next_shape + # get next AABB from block shape stack -execute store result score #x bs.ctx run data get storage bs:ctx _[-1][0] 625000 -execute store result score #y bs.ctx run data get storage bs:ctx _[-1][1] 625000 -execute store result score #z bs.ctx run data get storage bs:ctx _[-1][2] 625000 -execute store result score #i bs.ctx run data get storage bs:ctx _[-1][3] 625000 -execute store result score #j bs.ctx run data get storage bs:ctx _[-1][4] 625000 -execute store result score #k bs.ctx run data get storage bs:ctx _[-1][5] 625000 -data remove storage bs:ctx _[-1] +execute store result score #x bs.ctx run data get storage bs:lambda hitbox.shape[-1][0] 625000 +execute store result score #y bs.ctx run data get storage bs:lambda hitbox.shape[-1][1] 625000 +execute store result score #z bs.ctx run data get storage bs:lambda hitbox.shape[-1][2] 625000 +execute store result score #i bs.ctx run data get storage bs:lambda hitbox.shape[-1][3] 625000 +execute store result score #j bs.ctx run data get storage bs:lambda hitbox.shape[-1][4] 625000 +execute store result score #k bs.ctx run data get storage bs:lambda hitbox.shape[-1][5] 625000 +data remove storage bs:lambda hitbox.shape[-1] # offset hitbox coordinates by relative position scoreboard players operation #x bs.ctx += #p bs.ctx @@ -34,4 +36,6 @@ scoreboard players operation #k bs.ctx += #q bs.ctx function bs.move:collision/check/aabb # continue checking remaining AABBs in the shape if any -execute if data storage bs:ctx _[0] run function bs.move:collision/check/block/shape +execute store result score #move.hit_flag bs.data store result storage bs:ctx y int 1 run data get storage bs:lambda hitbox.shape[-1][6] +execute if score #move.hit_flag bs.data matches 0 store result storage bs:ctx y int 1 run scoreboard players set #move.hit_flag bs.data 1 +execute if data storage bs:lambda hitbox.shape[-1] run function bs.move:collision/check/block/shape with storage bs:ctx diff --git a/modules/bs.move/data/bs.move/function/collision/check/entity/any.mcfunction b/modules/bs.move/data/bs.move/function/collision/check/entity/any.mcfunction index 05a2a281fe..94072e0ba4 100644 --- a/modules/bs.move/data/bs.move/function/collision/check/entity/any.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/check/entity/any.mcfunction @@ -45,4 +45,5 @@ scoreboard players operation #j bs.ctx += #h bs.ctx scoreboard players operation #k bs.ctx += #d bs.ctx # perform AABB collision check +execute store result storage bs:ctx y int 1 run scoreboard players set #move.hit_flag bs.data -1 function bs.move:collision/check/aabb diff --git a/modules/bs.move/data/bs.move/function/collision/check/entity/custom.mcfunction b/modules/bs.move/data/bs.move/function/collision/check/entity/custom.mcfunction index fb5bbe1cf0..ba930f0a43 100644 --- a/modules/bs.move/data/bs.move/function/collision/check/entity/custom.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/check/entity/custom.mcfunction @@ -34,4 +34,5 @@ scoreboard players operation #j bs.ctx += @s bs.height scoreboard players operation #k bs.ctx += @s bs.depth # perform AABB collision check +execute store result storage bs:ctx y int 1 run scoreboard players set #move.hit_flag bs.data -1 function bs.move:collision/check/aabb diff --git a/modules/bs.move/data/bs.move/function/collision/check/run.mcfunction b/modules/bs.move/data/bs.move/function/collision/check/init.mcfunction similarity index 96% rename from modules/bs.move/data/bs.move/function/collision/check/run.mcfunction rename to modules/bs.move/data/bs.move/function/collision/check/init.mcfunction index 5cf1952f70..08e477cec3 100644 --- a/modules/bs.move/data/bs.move/function/collision/check/run.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/check/init.mcfunction @@ -13,4 +13,4 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -$execute align xyz positioned ~$(sx) ~$(sy) ~$(sz) run function bs.move:collision/check/kind +$execute align xyz positioned ~$(sx) ~$(sy) ~$(sz) run function bs.move:collision/check/any diff --git a/modules/bs.move/data/bs.move/function/collision/collide.mcfunction b/modules/bs.move/data/bs.move/function/collision/collide.mcfunction index 476eebd945..802e4df263 100644 --- a/modules/bs.move/data/bs.move/function/collision/collide.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/collide.mcfunction @@ -13,6 +13,10 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ +$execute if score #move.flag.$(y) bs.data matches 1 if score #move.hit_flag bs.data matches $(y) run return run tag @s add bs.move.flag.$(y) +$execute if score #x bs.ctx matches ..-1 if score #move.hit_flag bs.data matches $(y) run return run tag @s add bs.move.flag.$(y) +execute if score #move.toi bs.data <= #x bs.ctx run return 0 + # get the travelled distance and the surface that was hit scoreboard players operation #move.toi bs.data = #x bs.ctx execute if score #move.vx bs.data matches ..-1 run scoreboard players set $move.hit_face bs.lambda 5 @@ -21,3 +25,4 @@ execute if score #move.toi bs.data = #z bs.ctx if score #move.vz bs.data matches execute if score #move.toi bs.data = #z bs.ctx if score #move.vz bs.data matches 0.. run scoreboard players set $move.hit_face bs.lambda 2 execute if score #move.toi bs.data = #y bs.ctx if score #move.vy bs.data matches ..-1 run scoreboard players set $move.hit_face bs.lambda 1 execute if score #move.toi bs.data = #y bs.ctx if score #move.vy bs.data matches 0.. run scoreboard players set $move.hit_face bs.lambda 0 +scoreboard players operation $move.hit_flag bs.lambda = #move.hit_flag bs.data diff --git a/modules/bs.move/data/bs.move/function/collision/handle.mcfunction b/modules/bs.move/data/bs.move/function/collision/handle.mcfunction index 44b8e6ba0a..2af2df1c99 100644 --- a/modules/bs.move/data/bs.move/function/collision/handle.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/handle.mcfunction @@ -14,6 +14,7 @@ # ------------------------------------------------------------------------------------------------------------ # get starting position and velocity vector +scoreboard players add #move.it bs.data 1 execute summon minecraft:marker run function bs.move:collision/utils/get_starting_pos execute store result score #move.rx bs.data run data get storage bs:ctx _[0] 10000000 execute store result score #move.ry bs.data run data get storage bs:ctx _[1] 10000000 @@ -28,22 +29,30 @@ scoreboard players operation #move.vz bs.data -= #move.rz bs.data # compute entity bounding box and volume to check for collisions function bs.move:collision/utils/get_bounding_box -execute if score #move.vx bs.data matches 0.. run function bs.move:collision/setup/xp -execute if score #move.vy bs.data matches 0.. run function bs.move:collision/setup/yp -execute if score #move.vz bs.data matches 0.. run function bs.move:collision/setup/zp -execute if score #move.vx bs.data matches ..-1 run function bs.move:collision/setup/xn -execute if score #move.vy bs.data matches ..-1 run function bs.move:collision/setup/yn -execute if score #move.vz bs.data matches ..-1 run function bs.move:collision/setup/zn +execute if score #move.vx bs.data matches 0.. run function bs.move:collision/utils/setup_xp +execute if score #move.vy bs.data matches 0.. run function bs.move:collision/utils/setup_yp +execute if score #move.vz bs.data matches 0.. run function bs.move:collision/utils/setup_zp +execute if score #move.vx bs.data matches ..-1 run function bs.move:collision/utils/setup_xn +execute if score #move.vy bs.data matches ..-1 run function bs.move:collision/utils/setup_yn +execute if score #move.vz bs.data matches ..-1 run function bs.move:collision/utils/setup_zn # run collision detection and run resolver function if needed scoreboard players set #move.toi bs.data 10000 +execute store success score #move.flag.1 bs.data if entity @s[tag=bs.move.flag.1] +execute store success score #move.flag.2 bs.data if entity @s[tag=bs.move.flag.2] +execute store success score #move.flag.4 bs.data if entity @s[tag=bs.move.flag.4] +execute store success score #move.flag.8 bs.data if entity @s[tag=bs.move.flag.8] +tag @s remove bs.move.flag.1 +tag @s remove bs.move.flag.2 +tag @s remove bs.move.flag.4 +tag @s remove bs.move.flag.8 # @deprecated hitbox_shape (update following lines in in 4.0.0) +function bs.move:collision/utils/setup_tags execute if data storage bs:data move{blocks:1b} run data modify storage bs:data move.blocks set from storage bs:data move.hitbox_shape execute if data storage bs:data move{blocks:1b} run data modify storage bs:data move.blocks set value "collision" -execute if data storage bs:data move{blocks:"collision"} run data modify storage bs:data move.blocks set value "function #bs.hitbox:get_block_collision" -execute if data storage bs:data move{blocks:"interaction"} run data modify storage bs:data move.blocks set value "function #bs.hitbox:get_block_shape" +execute if data storage bs:data move{blocks:"collision"} run data modify storage bs:data move.blocks set value "function #bs.hitbox:callback/get_block_collision" +execute if data storage bs:data move{blocks:"interaction"} run data modify storage bs:data move.blocks set value "function #bs.hitbox:callback/get_block_shape" execute if data storage bs:data move{entities:1b} run data modify storage bs:data move.entities set value "!bs.move.omit" -function bs.move:collision/utils/setup_tags -function bs.move:collision/check/run with storage bs:data move +function bs.move:collision/check/init with storage bs:data move function bs.move:collision/utils/reset_tags -$execute if score #move.toi bs.data matches -100..9999 run function bs.move:collision/resolve/$(resolver) with storage bs:data move +$execute if score #move.toi bs.data matches 0..9999 run function bs.move:collision/resolve/$(resolver) with storage bs:data move diff --git a/modules/bs.move/data/bs.move/function/collision/resolve/canonical.mcfunction b/modules/bs.move/data/bs.move/function/collision/resolve/canonical.mcfunction index e1fb6a31cc..3ee7d68768 100644 --- a/modules/bs.move/data/bs.move/function/collision/resolve/canonical.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/resolve/canonical.mcfunction @@ -16,7 +16,5 @@ # resolve collision using the on_collision callback function bs.move:collision/resolve/toi $$(on_collision) -execute store result storage bs:ctx x double .0000001 run scoreboard players get $move.vel.x bs.lambda -execute store result storage bs:ctx y double .0000001 run scoreboard players get $move.vel.y bs.lambda -execute store result storage bs:ctx z double .0000001 run scoreboard players get $move.vel.z bs.lambda -execute unless data storage bs:ctx {x:0d,y:0d,z:0d} at @s run function bs.move:teleport/canonical/run with storage bs:ctx +execute store result storage bs:ctx y int 1 run scoreboard players get $move.hit_flag bs.lambda +function bs.move:collision/resolve/vel with storage bs:ctx diff --git a/modules/bs.move/data/bs.move/function/collision/resolve/local.mcfunction b/modules/bs.move/data/bs.move/function/collision/resolve/local.mcfunction index c91c8f23ac..49e019df3b 100644 --- a/modules/bs.move/data/bs.move/function/collision/resolve/local.mcfunction +++ b/modules/bs.move/data/bs.move/function/collision/resolve/local.mcfunction @@ -17,8 +17,6 @@ function bs.move:collision/resolve/toi execute rotated as @s run function #bs.move:local_to_canonical $$(on_collision) -execute store result storage bs:ctx x double .0000001 run scoreboard players get $move.vel.x bs.lambda -execute store result storage bs:ctx y double .0000001 run scoreboard players get $move.vel.y bs.lambda -execute store result storage bs:ctx z double .0000001 run scoreboard players get $move.vel.z bs.lambda -execute unless data storage bs:ctx {x:0d,y:0d,z:0d} at @s run function bs.move:teleport/canonical/run with storage bs:ctx +execute store result storage bs:ctx y int 1 run scoreboard players get $move.hit_flag bs.lambda +function bs.move:collision/resolve/vel with storage bs:ctx execute rotated as @s run function #bs.move:canonical_to_local diff --git a/modules/bs.move/data/bs.move/function/collision/resolve/vel.mcfunction b/modules/bs.move/data/bs.move/function/collision/resolve/vel.mcfunction new file mode 100644 index 0000000000..9b1ca7edac --- /dev/null +++ b/modules/bs.move/data/bs.move/function/collision/resolve/vel.mcfunction @@ -0,0 +1,27 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute store result storage bs:ctx x double .0000001 run scoreboard players get $move.vel.x bs.lambda +execute store result storage bs:ctx y double .0000001 run scoreboard players get $move.vel.y bs.lambda +execute store result storage bs:ctx z double .0000001 run scoreboard players get $move.vel.z bs.lambda + +$execute if score $move.hit_face bs.lambda matches 5 if score $move.vel.x bs.lambda matches ..-1 run tag @s add bs.move.flag.$(y) +$execute if score $move.hit_face bs.lambda matches 4 if score $move.vel.x bs.lambda matches 1.. run tag @s add bs.move.flag.$(y) +$execute if score $move.hit_face bs.lambda matches 3 if score $move.vel.z bs.lambda matches ..-1 run tag @s add bs.move.flag.$(y) +$execute if score $move.hit_face bs.lambda matches 2 if score $move.vel.z bs.lambda matches 1.. run tag @s add bs.move.flag.$(y) +$execute if score $move.hit_face bs.lambda matches 1 if score $move.vel.y bs.lambda matches ..-1 run tag @s add bs.move.flag.$(y) +$execute if score $move.hit_face bs.lambda matches 0 if score $move.vel.y bs.lambda matches 1.. run tag @s add bs.move.flag.$(y) + +execute if score #move.it bs.data matches ..2 unless data storage bs:ctx {x:0d,y:0d,z:0d} at @s run function bs.move:teleport/canonical/run with storage bs:ctx diff --git a/modules/bs.move/data/bs.move/function/collision/setup/xn.mcfunction b/modules/bs.move/data/bs.move/function/collision/utils/setup_xn.mcfunction similarity index 100% rename from modules/bs.move/data/bs.move/function/collision/setup/xn.mcfunction rename to modules/bs.move/data/bs.move/function/collision/utils/setup_xn.mcfunction diff --git a/modules/bs.move/data/bs.move/function/collision/setup/xp.mcfunction b/modules/bs.move/data/bs.move/function/collision/utils/setup_xp.mcfunction similarity index 100% rename from modules/bs.move/data/bs.move/function/collision/setup/xp.mcfunction rename to modules/bs.move/data/bs.move/function/collision/utils/setup_xp.mcfunction diff --git a/modules/bs.move/data/bs.move/function/collision/setup/yn.mcfunction b/modules/bs.move/data/bs.move/function/collision/utils/setup_yn.mcfunction similarity index 100% rename from modules/bs.move/data/bs.move/function/collision/setup/yn.mcfunction rename to modules/bs.move/data/bs.move/function/collision/utils/setup_yn.mcfunction diff --git a/modules/bs.move/data/bs.move/function/collision/setup/yp.mcfunction b/modules/bs.move/data/bs.move/function/collision/utils/setup_yp.mcfunction similarity index 100% rename from modules/bs.move/data/bs.move/function/collision/setup/yp.mcfunction rename to modules/bs.move/data/bs.move/function/collision/utils/setup_yp.mcfunction diff --git a/modules/bs.move/data/bs.move/function/collision/setup/zn.mcfunction b/modules/bs.move/data/bs.move/function/collision/utils/setup_zn.mcfunction similarity index 100% rename from modules/bs.move/data/bs.move/function/collision/setup/zn.mcfunction rename to modules/bs.move/data/bs.move/function/collision/utils/setup_zn.mcfunction diff --git a/modules/bs.move/data/bs.move/function/collision/setup/zp.mcfunction b/modules/bs.move/data/bs.move/function/collision/utils/setup_zp.mcfunction similarity index 100% rename from modules/bs.move/data/bs.move/function/collision/setup/zp.mcfunction rename to modules/bs.move/data/bs.move/function/collision/utils/setup_zp.mcfunction diff --git a/modules/bs.move/data/bs.move/function/teleport/canonical/apply_vel.mcfunction b/modules/bs.move/data/bs.move/function/teleport/canonical/apply_vel.mcfunction index 3aa2a75808..544a4f91d0 100644 --- a/modules/bs.move/data/bs.move/function/teleport/canonical/apply_vel.mcfunction +++ b/modules/bs.move/data/bs.move/function/teleport/canonical/apply_vel.mcfunction @@ -18,4 +18,5 @@ $execute store result storage bs:ctx x double $(scale) run scoreboard players ge $execute store result storage bs:ctx y double $(scale) run scoreboard players get @s bs.vel.y $execute store result storage bs:ctx z double $(scale) run scoreboard players get @s bs.vel.z +scoreboard players set #move.it bs.data 0 execute at @s run function bs.move:teleport/canonical/run with storage bs:ctx diff --git a/modules/bs.move/data/bs.move/function/teleport/canonical/run.mcfunction b/modules/bs.move/data/bs.move/function/teleport/canonical/run.mcfunction index 90196a18bb..8548a9c768 100644 --- a/modules/bs.move/data/bs.move/function/teleport/canonical/run.mcfunction +++ b/modules/bs.move/data/bs.move/function/teleport/canonical/run.mcfunction @@ -14,5 +14,4 @@ # ------------------------------------------------------------------------------------------------------------ $tp @s ~$(x) ~$(y) ~$(z) - -execute unless data storage bs:data move{blocks:0b,entities:0b} run function bs.move:collision/handle {resolver:"canonical"} +function bs.move:collision/handle {resolver:"canonical"} diff --git a/modules/bs.move/data/bs.move/function/teleport/local/apply_local_vel.mcfunction b/modules/bs.move/data/bs.move/function/teleport/local/apply_local_vel.mcfunction index 1c8b83f7b4..d0af1b7949 100644 --- a/modules/bs.move/data/bs.move/function/teleport/local/apply_local_vel.mcfunction +++ b/modules/bs.move/data/bs.move/function/teleport/local/apply_local_vel.mcfunction @@ -18,4 +18,5 @@ $execute store result storage bs:ctx x double $(scale) run scoreboard players ge $execute store result storage bs:ctx y double $(scale) run scoreboard players get @s bs.vel.y $execute store result storage bs:ctx z double $(scale) run scoreboard players get @s bs.vel.z +scoreboard players set #move.it bs.data 0 execute at @s run function bs.move:teleport/local/run with storage bs:ctx diff --git a/modules/bs.move/data/bs.move/function/teleport/local/run.mcfunction b/modules/bs.move/data/bs.move/function/teleport/local/run.mcfunction index fa8fad3253..e07f9595ec 100644 --- a/modules/bs.move/data/bs.move/function/teleport/local/run.mcfunction +++ b/modules/bs.move/data/bs.move/function/teleport/local/run.mcfunction @@ -14,5 +14,4 @@ # ------------------------------------------------------------------------------------------------------------ $tp @s ^$(x) ^$(y) ^$(z) - -execute unless data storage bs:data move{blocks:0b,entities:0b} run function bs.move:collision/handle {resolver:"local"} +function bs.move:collision/handle {resolver:"local"} diff --git a/modules/bs.move/data/bs.move/tags/function/apply_local_vel.json b/modules/bs.move/data/bs.move/tags/function/apply_local_vel.json index 8688056255..fea7057689 100644 --- a/modules/bs.move/data/bs.move/tags/function/apply_local_vel.json +++ b/modules/bs.move/data/bs.move/tags/function/apply_local_vel.json @@ -11,8 +11,8 @@ "minecraft_version": "1.13" }, "updated": { - "date": "2025/10/06", - "minecraft_version": "1.21.9" + "date": "2025/11/23", + "minecraft_version": "1.21.10" } }, "values": [ diff --git a/modules/bs.move/data/bs.move/tags/function/apply_vel.json b/modules/bs.move/data/bs.move/tags/function/apply_vel.json index 08093fe35f..6f4e14aa4c 100644 --- a/modules/bs.move/data/bs.move/tags/function/apply_vel.json +++ b/modules/bs.move/data/bs.move/tags/function/apply_vel.json @@ -11,8 +11,8 @@ "minecraft_version": "1.13" }, "updated": { - "date": "2025/10/06", - "minecraft_version": "1.21.9" + "date": "2025/11/23", + "minecraft_version": "1.21.10" } }, "values": [ diff --git a/modules/bs.raycast/data/bs.raycast/function/__load__.mcfunction b/modules/bs.raycast/data/bs.raycast/function/__load__.mcfunction index b1051fcf41..f675bc2a6c 100644 --- a/modules/bs.raycast/data/bs.raycast/function/__load__.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/__load__.mcfunction @@ -20,7 +20,7 @@ scoreboard objectives add bs.ctx dummy [{text:"BS ",color:"dark_gray"},{text:"Co scoreboard objectives add bs.const dummy [{text:"BS ",color:"dark_gray"},{text:"Constants",color:"aqua"}] scoreboard objectives add bs.lambda dummy [{text:"BS ",color:"dark_gray"},{text:"Lambda",color:"aqua"}] scoreboard objectives add bs.data dummy [{text:"BS ",color:"dark_gray"},{text:"Data",color:"aqua"}] -scoreboard objectives add bs.tmin dummy [{text:"BS ",color:"dark_gray"},{text:"Near Collision",color:"aqua"}] +scoreboard objectives add bs.toi dummy [{text:"BS ",color:"dark_gray"},{text:"Time of Impact",color:"aqua"}] scoreboard players set -2 bs.const -2 scoreboard players set -1 bs.const -1 diff --git a/modules/bs.raycast/data/bs.raycast/function/__unload__.mcfunction b/modules/bs.raycast/data/bs.raycast/function/__unload__.mcfunction index 9fc4cbbec6..c00f0a6526 100644 --- a/modules/bs.raycast/data/bs.raycast/function/__unload__.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/__unload__.mcfunction @@ -20,7 +20,7 @@ scoreboard objectives remove bs.ctx scoreboard objectives remove bs.const scoreboard objectives remove bs.lambda scoreboard objectives remove bs.data -scoreboard objectives remove bs.tmin +scoreboard objectives remove bs.toi data remove storage bs:lambda raycast data remove storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/check/block/any.mcfunction b/modules/bs.raycast/data/bs.raycast/function/check/block/any.mcfunction index ba037e1f2b..12221f3537 100644 --- a/modules/bs.raycast/data/bs.raycast/function/check/block/any.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/check/block/any.mcfunction @@ -13,18 +13,18 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -execute if block ~ ~ ~ #bs.hitbox:is_full_cube run return run function bs.raycast:collide/record/cube +data remove storage bs:lambda hitbox +scoreboard players set $raycast.hit_flag bs.lambda 0 +$execute store result score $raycast.hit_flag bs.lambda run $(blocks) +execute if score $raycast.hit_flag bs.lambda matches 1.. unless data storage bs:lambda hitbox run return run function bs.raycast:collide/cube -$$(blocks) -execute unless data storage bs:out hitbox.shape run return 0 -data modify storage bs:ctx _ set from storage bs:out hitbox.shape -execute store result score #p bs.ctx run data get storage bs:out hitbox.offset.x 10000000 -execute store result score #q bs.ctx run data get storage bs:out hitbox.offset.z 10000000 +execute store result score #p bs.ctx run data get storage bs:lambda hitbox.offset.x 10000000 +execute store result score #q bs.ctx run data get storage bs:lambda hitbox.offset.z 10000000 execute if score #raycast.ux bs.data matches 0.. run scoreboard players operation #raycast.lx bs.data -= #raycast.dx bs.data execute if score #raycast.uy bs.data matches 0.. run scoreboard players operation #raycast.ly bs.data -= #raycast.dy bs.data execute if score #raycast.uz bs.data matches 0.. run scoreboard players operation #raycast.lz bs.data -= #raycast.dz bs.data -function bs.raycast:check/block/shape +execute if data storage bs:lambda hitbox.shape[-1] run function bs.raycast:check/block/shape execute if score #raycast.ux bs.data matches 0.. run scoreboard players operation #raycast.lx bs.data += #raycast.dx bs.data execute if score #raycast.uy bs.data matches 0.. run scoreboard players operation #raycast.ly bs.data += #raycast.dy bs.data execute if score #raycast.uz bs.data matches 0.. run scoreboard players operation #raycast.lz bs.data += #raycast.dz bs.data diff --git a/modules/bs.raycast/data/bs.raycast/function/check/block/shape.mcfunction b/modules/bs.raycast/data/bs.raycast/function/check/block/shape.mcfunction index e6eaaecc0c..bc255f3f5d 100644 --- a/modules/bs.raycast/data/bs.raycast/function/check/block/shape.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/check/block/shape.mcfunction @@ -14,13 +14,12 @@ # ------------------------------------------------------------------------------------------------------------ # get hitbox coordinates -execute store result score #x bs.ctx run data get storage bs:ctx _[-1][0] 625000 -execute store result score #y bs.ctx run data get storage bs:ctx _[-1][1] 625000 -execute store result score #z bs.ctx run data get storage bs:ctx _[-1][2] 625000 -execute store result score #i bs.ctx run data get storage bs:ctx _[-1][3] 625000 -execute store result score #j bs.ctx run data get storage bs:ctx _[-1][4] 625000 -execute store result score #k bs.ctx run data get storage bs:ctx _[-1][5] 625000 -data remove storage bs:ctx _[-1] +execute store result score #x bs.ctx run data get storage bs:lambda hitbox.shape[-1][0] 625000 +execute store result score #y bs.ctx run data get storage bs:lambda hitbox.shape[-1][1] 625000 +execute store result score #z bs.ctx run data get storage bs:lambda hitbox.shape[-1][2] 625000 +execute store result score #i bs.ctx run data get storage bs:lambda hitbox.shape[-1][3] 625000 +execute store result score #j bs.ctx run data get storage bs:lambda hitbox.shape[-1][4] 625000 +execute store result score #k bs.ctx run data get storage bs:lambda hitbox.shape[-1][5] 625000 # offset coordinates if needed scoreboard players operation #x bs.ctx += #p bs.ctx @@ -54,10 +53,10 @@ scoreboard players operation #i bs.ctx < #j bs.ctx scoreboard players operation #i bs.ctx < #k bs.ctx # check for valid intersection: near ≤ far and within ray bounds -execute if score #i bs.ctx matches 0.. \ +execute if score #x bs.ctx matches 0.. \ if score #x bs.ctx <= #i bs.ctx \ - if score #x bs.ctx < #raycast.btmin bs.data \ if score #x bs.ctx <= #raycast.max_distance bs.data \ run function bs.raycast:collide/record/shape -execute if data storage bs:ctx _[-1] run function bs.raycast:check/block/shape +data remove storage bs:lambda hitbox.shape[-1] +execute if data storage bs:lambda hitbox.shape[-1] run function bs.raycast:check/block/shape diff --git a/modules/bs.raycast/data/bs.raycast/function/check/entity/size.mcfunction b/modules/bs.raycast/data/bs.raycast/function/check/entity/size.mcfunction index 6c85bcb307..e94753ac93 100644 --- a/modules/bs.raycast/data/bs.raycast/function/check/entity/size.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/check/entity/size.mcfunction @@ -50,9 +50,9 @@ scoreboard players operation #i bs.ctx < #j bs.ctx scoreboard players operation #i bs.ctx < #k bs.ctx # check for valid intersection: near ≤ far and within ray bounds -execute if score #i bs.ctx matches 0.. \ +execute if score #x bs.ctx matches 0.. \ if score #x bs.ctx <= #i bs.ctx \ if score #x bs.ctx <= #raycast.max_distance bs.data \ run return run function bs.raycast:collide/record/size -scoreboard players set @s bs.tmin 2147483647 +scoreboard players set @s bs.toi 2147483647 diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/any.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/any.mcfunction index 7970d82488..cc3a7e8958 100644 --- a/modules/bs.raycast/data/bs.raycast/function/collide/any.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/collide/any.mcfunction @@ -14,15 +14,19 @@ # ------------------------------------------------------------------------------------------------------------ data remove storage bs:lambda raycast -execute store result storage bs:lambda raycast.distance double .001 run scoreboard players get #raycast.tmin bs.data -execute if score #raycast.tmin bs.data = #raycast.btmin bs.data run function bs.raycast:collide/block/at_block -execute if score #raycast.tmin bs.data = #raycast.etmin bs.data positioned as @s run function bs.raycast:collide/entity/at_origin +scoreboard players operation $raycast.pierce_distance bs.lambda -= $raycast.distance bs.lambda +scoreboard players operation $raycast.pierce_distance bs.lambda *= -1 bs.const +execute store result storage bs:lambda raycast.distance double .001 run scoreboard players get $raycast.distance bs.lambda +execute if score $raycast.distance bs.lambda = #raycast.btoi bs.data run function bs.raycast:collide/block/handle +execute if score $raycast.distance bs.lambda = #raycast.etoi bs.data positioned as @s run function bs.raycast:collide/entity/handle with storage bs:lambda raycast # stop the recursion if piercing is 0 execute if score $raycast.piercing bs.lambda matches 0 run return run scoreboard players set #raycast.max_distance bs.data -2147483648 -scoreboard players remove $raycast.piercing bs.lambda 1 +scoreboard players set $raycast.distance bs.lambda 2147483646 +scoreboard players operation $raycast.distance bs.lambda < #raycast.btoi bs.data +scoreboard players operation $raycast.distance bs.lambda < #raycast.etoi bs.data -scoreboard players set #raycast.tmin bs.data 2147483647 -scoreboard players operation #raycast.tmin bs.data < #raycast.btmin bs.data -scoreboard players operation #raycast.tmin bs.data < #raycast.etmin bs.data -execute if score #raycast.tmin bs.data <= #raycast.lx bs.data if score #raycast.tmin bs.data <= #raycast.ly bs.data if score #raycast.tmin bs.data <= #raycast.lz bs.data run function bs.raycast:collide/any +execute if score $raycast.distance bs.lambda <= #raycast.lx bs.data \ + if score $raycast.distance bs.lambda <= #raycast.ly bs.data \ + if score $raycast.distance bs.lambda <= #raycast.lz bs.data \ + run function bs.raycast:collide/any diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/block/handle.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/block/handle.mcfunction new file mode 100644 index 0000000000..690195b28f --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/collide/block/handle.mcfunction @@ -0,0 +1,38 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute store result score #n bs.ctx run data get storage bs:data raycast.record[-1].norm +execute if score #n bs.ctx matches 1 if score #raycast.ux bs.data matches ..-1 run scoreboard players set $raycast.hit_face bs.lambda 5 +execute if score #n bs.ctx matches 1 if score #raycast.ux bs.data matches 0.. run scoreboard players set $raycast.hit_face bs.lambda 4 +execute if score #n bs.ctx matches 2 if score #raycast.uz bs.data matches ..-1 run scoreboard players set $raycast.hit_face bs.lambda 3 +execute if score #n bs.ctx matches 2 if score #raycast.uz bs.data matches 0.. run scoreboard players set $raycast.hit_face bs.lambda 2 +execute if score #n bs.ctx matches 3 if score #raycast.uy bs.data matches ..-1 run scoreboard players set $raycast.hit_face bs.lambda 1 +execute if score #n bs.ctx matches 3 if score #raycast.uy bs.data matches 0.. run scoreboard players set $raycast.hit_face bs.lambda 0 + +execute if data storage bs:data raycast.data{hit_normal:1b} run function bs.raycast:utils/get_hit_normal +execute if data storage bs:data raycast.data{hit_point:1b} positioned as @s run function bs.raycast:utils/get_hit_point +execute if data storage bs:data raycast.data{targeted_block:1b} run function bs.raycast:utils/get_targeted_block + +execute if data storage bs:lambda hitbox run function bs.raycast:collide/block/target +execute store result score $raycast.hit_flag bs.lambda run data get storage bs:data raycast.record[-1].flag + +execute if data storage bs:data raycast.on_hit_point positioned as @s run function bs.raycast:collide/block/point + +scoreboard players operation #raycast.bpiercing bs.data = $raycast.piercing bs.lambda +execute unless data storage bs:data raycast.piercing{} run scoreboard players operation #raycast.epiercing bs.data = #raycast.bpiercing bs.data + +data remove storage bs:data raycast.record[-1] +execute unless data storage bs:data raycast.record[-1] run return run scoreboard players set #raycast.btoi bs.data 2147483647 +execute store result score #raycast.btoi bs.data run data get storage bs:data raycast.record[-1].tmin diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/block/at_origin.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/block/point.mcfunction similarity index 77% rename from modules/bs.raycast/data/bs.raycast/function/collide/block/at_origin.mcfunction rename to modules/bs.raycast/data/bs.raycast/function/collide/block/point.mcfunction index 02c0eb2225..f6e7f06458 100644 --- a/modules/bs.raycast/data/bs.raycast/function/collide/block/at_origin.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/collide/block/point.mcfunction @@ -13,6 +13,6 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -function bs.raycast:utils/get_hit_point with storage bs:lambda raycast -execute if data storage bs:data raycast.on_hit_point positioned as @s run function bs.raycast:utils/on_hit_point with storage bs:data raycast +function bs.raycast:utils/tp_hit_point with storage bs:lambda raycast +execute positioned as @s run function bs.raycast:utils/on_hit_point with storage bs:data raycast tp @s ~ ~ ~ diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/block/target.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/block/target.mcfunction new file mode 100644 index 0000000000..359d8aa593 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/collide/block/target.mcfunction @@ -0,0 +1,28 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +data remove storage bs:lambda hitbox + +execute if score #raycast.bpiercing bs.data matches 0.. run scoreboard players remove #raycast.bpiercing bs.data 1 +scoreboard players operation $raycast.piercing bs.lambda = #raycast.bpiercing bs.data + +scoreboard players set $raycast.hit_flag bs.lambda 0 +execute if data storage bs:data raycast.record[{flag:1}] run scoreboard players add $raycast.hit_flag bs.lambda 1 +execute if data storage bs:data raycast.record[{flag:2}] run scoreboard players add $raycast.hit_flag bs.lambda 2 +execute if data storage bs:data raycast.record[{flag:4}] run scoreboard players add $raycast.hit_flag bs.lambda 4 +execute if data storage bs:data raycast.record[{flag:8}] run scoreboard players add $raycast.hit_flag bs.lambda 8 +execute unless data storage bs:data raycast.on_hit_point run data remove storage bs:data raycast.record + +execute if data storage bs:data raycast.on_targeted_block run function bs.raycast:utils/on_targeted_block with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/cube.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/cube.mcfunction new file mode 100644 index 0000000000..6214516577 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/collide/cube.mcfunction @@ -0,0 +1,52 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute if score #raycast.bpiercing bs.data matches 0.. run scoreboard players remove #raycast.bpiercing bs.data 1 +scoreboard players operation $raycast.piercing bs.lambda = #raycast.bpiercing bs.data + +execute store result score $raycast.distance bs.lambda run scoreboard players operation #raycast.lx bs.data -= #raycast.dx bs.data +scoreboard players operation #raycast.ly bs.data -= #raycast.dy bs.data +scoreboard players operation #raycast.lz bs.data -= #raycast.dz bs.data +scoreboard players operation $raycast.distance bs.lambda > #raycast.ly bs.data +scoreboard players operation $raycast.distance bs.lambda > #raycast.lz bs.data + +scoreboard players operation $raycast.pierce_distance bs.lambda -= $raycast.distance bs.lambda +scoreboard players operation $raycast.pierce_distance bs.lambda *= -1 bs.const + +execute if score #raycast.ux bs.data matches ..-1 run scoreboard players set $raycast.hit_face bs.lambda 5 +execute if score #raycast.ux bs.data matches 0.. run scoreboard players set $raycast.hit_face bs.lambda 4 +execute if score $raycast.distance bs.lambda = #raycast.lz bs.data if score #raycast.uz bs.data matches ..-1 run scoreboard players set $raycast.hit_face bs.lambda 3 +execute if score $raycast.distance bs.lambda = #raycast.lz bs.data if score #raycast.uz bs.data matches 0.. run scoreboard players set $raycast.hit_face bs.lambda 2 +execute if score $raycast.distance bs.lambda = #raycast.ly bs.data if score #raycast.uy bs.data matches ..-1 run scoreboard players set $raycast.hit_face bs.lambda 1 +execute if score $raycast.distance bs.lambda = #raycast.ly bs.data if score #raycast.uy bs.data matches 0.. run scoreboard players set $raycast.hit_face bs.lambda 0 + +data remove storage bs:lambda raycast +execute store result storage bs:lambda raycast.distance double .001 run scoreboard players get $raycast.distance bs.lambda +execute if data storage bs:data raycast.data{hit_normal:1b} run function bs.raycast:utils/get_hit_normal +execute if data storage bs:data raycast.data{hit_point:1b} positioned as @s run function bs.raycast:utils/get_hit_point +execute if data storage bs:data raycast.data{targeted_block:1b} run function bs.raycast:utils/get_targeted_block + +execute if data storage bs:data raycast.on_targeted_block run function bs.raycast:utils/on_targeted_block with storage bs:data raycast +execute if data storage bs:data raycast.on_hit_point positioned as @s run function bs.raycast:collide/block/point + +execute if score $raycast.piercing bs.lambda matches 0 run return run scoreboard players set #raycast.max_distance bs.data -2147483648 + +scoreboard players operation $raycast.distance bs.lambda = #raycast.etoi bs.data +scoreboard players operation #raycast.bpiercing bs.data = $raycast.piercing bs.lambda +execute unless data storage bs:data raycast.piercing{} run scoreboard players operation #raycast.epiercing bs.data = #raycast.bpiercing bs.data + +scoreboard players operation #raycast.lx bs.data += #raycast.dx bs.data +scoreboard players operation #raycast.ly bs.data += #raycast.dy bs.data +scoreboard players operation #raycast.lz bs.data += #raycast.dz bs.data diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/entity/as_entity.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/entity/as_entity.mcfunction deleted file mode 100644 index 86c20fae02..0000000000 --- a/modules/bs.raycast/data/bs.raycast/function/collide/entity/as_entity.mcfunction +++ /dev/null @@ -1,26 +0,0 @@ -# ------------------------------------------------------------------------------------------------------------ -# 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. -# ------------------------------------------------------------------------------------------------------------ - -execute store result score #raycast.etmin bs.data run scoreboard players set @s bs.tmin 2147483647 -scoreboard players operation #raycast.etmin bs.data < @e[distance=..255,scores={bs.tmin=0..}] bs.tmin - -data modify storage bs:lambda raycast.targeted_entity set from entity @s UUID - -data modify storage bs:lambda raycast.hit_normal set value [0,0,0] -execute if entity @s[tag=bs.raycast.normx] store result storage bs:lambda raycast.hit_normal[0] int -1 run data get storage bs:data raycast.sx -execute if entity @s[tag=bs.raycast.normy] store result storage bs:lambda raycast.hit_normal[1] int -1 run data get storage bs:data raycast.sy -execute if entity @s[tag=bs.raycast.normz] store result storage bs:lambda raycast.hit_normal[2] int -1 run data get storage bs:data raycast.sz - -execute if data storage bs:data raycast.on_targeted_entity at @s run function bs.raycast:utils/on_targeted_entity with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/entity/at_origin.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/entity/handle.mcfunction similarity index 58% rename from modules/bs.raycast/data/bs.raycast/function/collide/entity/at_origin.mcfunction rename to modules/bs.raycast/data/bs.raycast/function/collide/entity/handle.mcfunction index c29944e133..6c510301e7 100644 --- a/modules/bs.raycast/data/bs.raycast/function/collide/entity/at_origin.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/collide/entity/handle.mcfunction @@ -13,7 +13,10 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -function bs.raycast:utils/get_hit_point with storage bs:lambda raycast -execute positioned as @s as @n[predicate=bs.raycast:collide,distance=..24,sort=arbitrary] run function bs.raycast:collide/entity/as_entity -execute if data storage bs:data raycast.on_hit_point positioned as @s run function bs.raycast:utils/on_hit_point with storage bs:data raycast +$tp @s ^ ^ ^$(distance) +execute if data storage bs:data raycast.data{hit_point:1b} run data modify storage bs:lambda raycast.hit_point set from entity @s Pos +execute positioned as @s as @n[predicate=bs.raycast:internal/collide,distance=..24,sort=arbitrary] run function bs.raycast:collide/entity/target tp @s ~ ~ ~ + +scoreboard players operation #raycast.epiercing bs.data = $raycast.piercing bs.lambda +execute unless data storage bs:data raycast.piercing{} run scoreboard players operation #raycast.bpiercing bs.data = #raycast.epiercing bs.data diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/entity/target.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/entity/target.mcfunction new file mode 100644 index 0000000000..ea0a427167 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/collide/entity/target.mcfunction @@ -0,0 +1,34 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute if score #raycast.epiercing bs.data matches 0.. run scoreboard players remove #raycast.epiercing bs.data 1 +scoreboard players operation $raycast.piercing bs.lambda = #raycast.epiercing bs.data + +scoreboard players set $raycast.hit_flag bs.lambda -1 +execute if entity @s[tag=bs.raycast.nx] if score #raycast.ux bs.data matches ..-1 run scoreboard players set $raycast.hit_face bs.lambda 5 +execute if entity @s[tag=bs.raycast.nx] if score #raycast.ux bs.data matches 0.. run scoreboard players set $raycast.hit_face bs.lambda 4 +execute if entity @s[tag=bs.raycast.nz] if score #raycast.uz bs.data matches ..-1 run scoreboard players set $raycast.hit_face bs.lambda 3 +execute if entity @s[tag=bs.raycast.nz] if score #raycast.uz bs.data matches 0.. run scoreboard players set $raycast.hit_face bs.lambda 2 +execute if entity @s[tag=bs.raycast.ny] if score #raycast.uy bs.data matches ..-1 run scoreboard players set $raycast.hit_face bs.lambda 1 +execute if entity @s[tag=bs.raycast.ny] if score #raycast.uy bs.data matches 0.. run scoreboard players set $raycast.hit_face bs.lambda 0 + +execute if data storage bs:data raycast.data{hit_normal:1b} run function bs.raycast:utils/get_hit_normal +execute if data storage bs:data raycast.data{targeted_entity:1b} run data modify storage bs:lambda raycast.targeted_entity set from entity @s UUID + +execute if data storage bs:data raycast.on_targeted_entity at @s run function bs.raycast:utils/on_targeted_entity with storage bs:data raycast +execute if data storage bs:data raycast.on_hit_point run function bs.raycast:utils/on_hit_point with storage bs:data raycast + +execute store result score #raycast.etoi bs.data run scoreboard players set @s bs.toi 2147483647 +scoreboard players operation #raycast.etoi bs.data < @e[distance=..255,scores={bs.toi=0..}] bs.toi diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/record/cube.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/record/cube.mcfunction deleted file mode 100644 index 875f6581f0..0000000000 --- a/modules/bs.raycast/data/bs.raycast/function/collide/record/cube.mcfunction +++ /dev/null @@ -1,29 +0,0 @@ -# ------------------------------------------------------------------------------------------------------------ -# 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. -# ------------------------------------------------------------------------------------------------------------ - -execute store result score #raycast.btmin bs.data run scoreboard players operation #raycast.lx bs.data -= #raycast.dx bs.data -scoreboard players operation #raycast.ly bs.data -= #raycast.dy bs.data -scoreboard players operation #raycast.lz bs.data -= #raycast.dz bs.data -scoreboard players operation #raycast.btmin bs.data > #raycast.ly bs.data -scoreboard players operation #raycast.btmin bs.data > #raycast.lz bs.data -scoreboard players operation #raycast.tmin bs.data < #raycast.btmin bs.data - -scoreboard players set #raycast.norm bs.data 0 -execute if score #raycast.ly bs.data = #raycast.btmin bs.data run scoreboard players set #raycast.norm bs.data 1 -execute if score #raycast.lz bs.data = #raycast.btmin bs.data run scoreboard players set #raycast.norm bs.data 2 - -scoreboard players operation #raycast.lx bs.data += #raycast.dx bs.data -scoreboard players operation #raycast.ly bs.data += #raycast.dy bs.data -scoreboard players operation #raycast.lz bs.data += #raycast.dz bs.data diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/record/shape.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/record/shape.mcfunction index 246de07088..40f93389fb 100644 --- a/modules/bs.raycast/data/bs.raycast/function/collide/record/shape.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/collide/record/shape.mcfunction @@ -13,9 +13,23 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -scoreboard players operation #raycast.btmin bs.data = #x bs.ctx -scoreboard players operation #raycast.tmin bs.data < #raycast.btmin bs.data +data modify storage bs:ctx _ set value {left:[],right:[],entry:{flag:1}} +execute store result score #n bs.ctx run scoreboard players set #f bs.ctx 1 +execute if score #z bs.ctx = #x bs.ctx run scoreboard players set #n bs.ctx 2 +execute if score #y bs.ctx = #x bs.ctx run scoreboard players set #n bs.ctx 3 +execute if data storage bs:lambda hitbox.shape[-1][6] \ + store result score #f bs.ctx store result storage bs:ctx _.entry.flag int 1 \ + run data get storage bs:lambda hitbox.shape[-1][6] -execute if score #z bs.ctx = #x bs.ctx run return run scoreboard players set #raycast.norm bs.data 2 -execute if score #y bs.ctx = #x bs.ctx run return run scoreboard players set #raycast.norm bs.data 1 -scoreboard players set #raycast.norm bs.data 0 +execute if score #x bs.ctx > #raycast.btoi bs.data run function bs.raycast:collide/record/slice/right +execute if data storage bs:data raycast.record[-1] run function bs.raycast:collide/record/slice/left +scoreboard players operation #raycast.btoi bs.data < #x bs.ctx +scoreboard players operation $raycast.distance bs.lambda < #raycast.btoi bs.data + +execute store result storage bs:ctx _.entry.tmin int 1 run scoreboard players get #x bs.ctx +execute store result storage bs:ctx _.entry.tmax int 1 run scoreboard players get #i bs.ctx +execute store result storage bs:ctx _.entry.norm int 1 run scoreboard players get #n bs.ctx + +data modify storage bs:data raycast.record append from storage bs:ctx _.left[] +data modify storage bs:data raycast.record append from storage bs:ctx _.entry +data modify storage bs:data raycast.record append from storage bs:ctx _.right[] diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/record/size.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/record/size.mcfunction index 4af7241004..776a98f1b7 100644 --- a/modules/bs.raycast/data/bs.raycast/function/collide/record/size.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/collide/record/size.mcfunction @@ -13,13 +13,13 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -scoreboard players operation @s bs.tmin = #x bs.ctx -scoreboard players operation #raycast.etmin bs.data < #x bs.ctx -scoreboard players operation #raycast.tmin bs.data < #raycast.etmin bs.data +scoreboard players operation @s bs.toi = #x bs.ctx +scoreboard players operation #raycast.etoi bs.data < #x bs.ctx +scoreboard players operation $raycast.distance bs.lambda < #raycast.etoi bs.data -tag @s remove bs.raycast.normx -tag @s remove bs.raycast.normy -tag @s remove bs.raycast.normz -execute if score #z bs.ctx = #x bs.ctx run return run tag @s add bs.raycast.normz -execute if score #y bs.ctx = #x bs.ctx run return run tag @s add bs.raycast.normy -tag @s add bs.raycast.normx +tag @s remove bs.raycast.nx +tag @s remove bs.raycast.ny +tag @s remove bs.raycast.nz +execute if score #z bs.ctx = #x bs.ctx run return run tag @s add bs.raycast.nz +execute if score #y bs.ctx = #x bs.ctx run return run tag @s add bs.raycast.ny +tag @s add bs.raycast.nx diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/left.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/left.mcfunction new file mode 100644 index 0000000000..c765ff0d80 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/left.mcfunction @@ -0,0 +1,21 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute store result score #u bs.ctx run data get storage bs:data raycast.record[-1].tmin +execute store result score #v bs.ctx run data get storage bs:data raycast.record[-1].flag +execute if score #v bs.ctx = #f bs.ctx if score #i bs.ctx >= #u bs.ctx run return run function bs.raycast:collide/record/slice/merge_left +data modify storage bs:ctx _.left prepend from storage bs:data raycast.record[-1] +data remove storage bs:data raycast.record[-1] +execute if data storage bs:data raycast.record[-1] unless score #v bs.ctx = #f bs.ctx run function bs.raycast:collide/record/slice/left diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/merge_left.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/merge_left.mcfunction new file mode 100644 index 0000000000..d665fed353 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/merge_left.mcfunction @@ -0,0 +1,17 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute store result score #i bs.ctx run data get storage bs:data raycast.record[-1].tmax +data remove storage bs:data raycast.record[-1] diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/merge_right.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/merge_right.mcfunction new file mode 100644 index 0000000000..384558d3b5 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/merge_right.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute store result score #x bs.ctx run data get storage bs:data raycast.record[-1].tmin +execute store result score #n bs.ctx run data get storage bs:data raycast.record[-1].norm +data remove storage bs:data raycast.record[-1] diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/right.mcfunction b/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/right.mcfunction new file mode 100644 index 0000000000..e56d567f28 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/collide/record/slice/right.mcfunction @@ -0,0 +1,22 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute store result score #u bs.ctx run data get storage bs:data raycast.record[-1].tmax +execute store result score #v bs.ctx run data get storage bs:data raycast.record[-1].flag +execute if score #v bs.ctx = #f bs.ctx if score #x bs.ctx <= #u bs.ctx run return run function bs.raycast:collide/record/slice/merge_right +data modify storage bs:ctx _.right prepend from storage bs:data raycast.record[-1] +data remove storage bs:data raycast.record[-1] +execute store result score #u bs.ctx run data get storage bs:data raycast.record[-1].tmin +execute if data storage bs:data raycast.record[-1] if score #x bs.ctx > #u bs.ctx run function bs.raycast:collide/record/slice/right diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/next.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/1/next.mcfunction similarity index 56% rename from modules/bs.raycast/data/bs.raycast/function/recurse/next.mcfunction rename to modules/bs.raycast/data/bs.raycast/function/recurse/1/next.mcfunction index 489306295e..0676d032a7 100644 --- a/modules/bs.raycast/data/bs.raycast/function/recurse/next.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/1/next.mcfunction @@ -13,12 +13,11 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -# check block and entity collision (debug: particle minecraft:block_marker{block_state:"barrier"} ~.5 ~.5 ~.5 0 0 0 0 1) -$execute unless data storage bs:data raycast{blocks:0b} unless block ~ ~ ~ $(ignored_blocks) run function bs.raycast:check/block/any with storage bs:data raycast -$execute unless data storage bs:data raycast{entities:0b} as @e[type=!$(ignored_entities),tag=$(entities),tag=!bs.hitbox.custom,predicate=!bs.raycast:checked,dx=0] run function bs.raycast:check/entity/any -execute if score #raycast.tmin bs.data <= #raycast.lx bs.data if score #raycast.tmin bs.data <= #raycast.ly bs.data if score #raycast.tmin bs.data <= #raycast.lz bs.data run function bs.raycast:collide/any +# check block collisions +$execute unless block ~ ~ ~ $(ignored_blocks) run function bs.raycast:check/block/any with storage bs:data raycast +execute if score #raycast.max_distance bs.data matches 1.. if score $raycast.distance bs.lambda <= #raycast.lx bs.data if score $raycast.distance bs.lambda <= #raycast.ly bs.data if score $raycast.distance bs.lambda <= #raycast.lz bs.data run function bs.raycast:collide/any # advance on the grid by the shortest length -execute if score #raycast.lx bs.data <= #raycast.ly bs.data if score #raycast.lx bs.data <= #raycast.lz bs.data if score #raycast.lx bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/x with storage bs:data raycast -execute if score #raycast.ly bs.data <= #raycast.lz bs.data if score #raycast.ly bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/y with storage bs:data raycast -execute if score #raycast.lz bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/z with storage bs:data raycast +execute if score #raycast.lx bs.data <= #raycast.ly bs.data if score #raycast.lx bs.data <= #raycast.lz bs.data if score #raycast.lx bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/1/x with storage bs:data raycast +execute if score #raycast.ly bs.data <= #raycast.lz bs.data if score #raycast.ly bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/1/y with storage bs:data raycast +execute if score #raycast.lz bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/1/z with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/x.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/1/x.mcfunction similarity index 95% rename from modules/bs.raycast/data/bs.raycast/function/recurse/x.mcfunction rename to modules/bs.raycast/data/bs.raycast/function/recurse/1/x.mcfunction index af897ec350..0f7fc737a6 100644 --- a/modules/bs.raycast/data/bs.raycast/function/recurse/x.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/1/x.mcfunction @@ -15,4 +15,4 @@ # increment length by delta on x then move to the next block on the grid scoreboard players operation #raycast.lx bs.data += #raycast.dx bs.data -$execute positioned ~$(sx) ~ ~ run return run function bs.raycast:recurse/next with storage bs:data raycast +$execute positioned ~$(sx) ~ ~ run return run function bs.raycast:recurse/1/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/y.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/1/y.mcfunction similarity index 95% rename from modules/bs.raycast/data/bs.raycast/function/recurse/y.mcfunction rename to modules/bs.raycast/data/bs.raycast/function/recurse/1/y.mcfunction index 85115e011f..183e49ffdd 100644 --- a/modules/bs.raycast/data/bs.raycast/function/recurse/y.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/1/y.mcfunction @@ -15,4 +15,4 @@ # increment length by delta on y then move to the next block on the grid scoreboard players operation #raycast.ly bs.data += #raycast.dy bs.data -$execute positioned ~ ~$(sy) ~ run return run function bs.raycast:recurse/next with storage bs:data raycast +$execute positioned ~ ~$(sy) ~ run return run function bs.raycast:recurse/1/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/z.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/1/z.mcfunction similarity index 95% rename from modules/bs.raycast/data/bs.raycast/function/recurse/z.mcfunction rename to modules/bs.raycast/data/bs.raycast/function/recurse/1/z.mcfunction index c503626879..e4b208b620 100644 --- a/modules/bs.raycast/data/bs.raycast/function/recurse/z.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/1/z.mcfunction @@ -15,4 +15,4 @@ # increment length by delta on z then move to the next block on the grid scoreboard players operation #raycast.lz bs.data += #raycast.dz bs.data -$execute positioned ~ ~ ~$(sz) run return run function bs.raycast:recurse/next with storage bs:data raycast +$execute positioned ~ ~ ~$(sz) run return run function bs.raycast:recurse/1/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/2/next.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/2/next.mcfunction new file mode 100644 index 0000000000..585593d909 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/2/next.mcfunction @@ -0,0 +1,23 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# check entity collisions +$execute as @e[type=!$(ignored_entities),tag=$(entities),predicate=!bs.raycast:internal/checked,dx=0,sort=nearest] run function bs.raycast:check/entity/any +execute if score $raycast.distance bs.lambda <= #raycast.lx bs.data if score $raycast.distance bs.lambda <= #raycast.ly bs.data if score $raycast.distance bs.lambda <= #raycast.lz bs.data run function bs.raycast:collide/any + +# advance on the grid by the shortest length +execute if score #raycast.lx bs.data <= #raycast.ly bs.data if score #raycast.lx bs.data <= #raycast.lz bs.data if score #raycast.lx bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/2/x with storage bs:data raycast +execute if score #raycast.ly bs.data <= #raycast.lz bs.data if score #raycast.ly bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/2/y with storage bs:data raycast +execute if score #raycast.lz bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/2/z with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/2/x.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/2/x.mcfunction new file mode 100644 index 0000000000..79b68d8c94 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/2/x.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on x then move to the next block on the grid +scoreboard players operation #raycast.lx bs.data += #raycast.dx bs.data +$execute positioned ~$(sx) ~ ~ run return run function bs.raycast:recurse/2/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/2/y.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/2/y.mcfunction new file mode 100644 index 0000000000..3d60bcba45 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/2/y.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on y then move to the next block on the grid +scoreboard players operation #raycast.ly bs.data += #raycast.dy bs.data +$execute positioned ~ ~$(sy) ~ run return run function bs.raycast:recurse/2/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/2/z.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/2/z.mcfunction new file mode 100644 index 0000000000..7b84e06f9c --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/2/z.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on z then move to the next block on the grid +scoreboard players operation #raycast.lz bs.data += #raycast.dz bs.data +$execute positioned ~ ~ ~$(sz) run return run function bs.raycast:recurse/2/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/3/next.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/3/next.mcfunction new file mode 100644 index 0000000000..00e41db95d --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/3/next.mcfunction @@ -0,0 +1,24 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# check entity and custom entity collisions +$execute as @e[tag=bs.hitbox.custom,tag=$(entities),predicate=!bs.raycast:internal/checked,distance=..24,sort=nearest] run function bs.raycast:check/entity/any +$execute as @e[type=!$(ignored_entities),tag=$(entities),predicate=!bs.raycast:internal/checked,dx=0,sort=nearest] run function bs.raycast:check/entity/any +execute if score $raycast.distance bs.lambda <= #raycast.lx bs.data if score $raycast.distance bs.lambda <= #raycast.ly bs.data if score $raycast.distance bs.lambda <= #raycast.lz bs.data run function bs.raycast:collide/any + +# advance on the grid by the shortest length +execute if score #raycast.lx bs.data <= #raycast.ly bs.data if score #raycast.lx bs.data <= #raycast.lz bs.data if score #raycast.lx bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/3/x with storage bs:data raycast +execute if score #raycast.ly bs.data <= #raycast.lz bs.data if score #raycast.ly bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/3/y with storage bs:data raycast +execute if score #raycast.lz bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/3/z with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/3/x.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/3/x.mcfunction new file mode 100644 index 0000000000..c8ecff493d --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/3/x.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on x then move to the next block on the grid +scoreboard players operation #raycast.lx bs.data += #raycast.dx bs.data +$execute positioned ~$(sx) ~ ~ run return run function bs.raycast:recurse/3/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/3/y.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/3/y.mcfunction new file mode 100644 index 0000000000..39cd685530 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/3/y.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on y then move to the next block on the grid +scoreboard players operation #raycast.ly bs.data += #raycast.dy bs.data +$execute positioned ~ ~$(sy) ~ run return run function bs.raycast:recurse/3/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/3/z.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/3/z.mcfunction new file mode 100644 index 0000000000..da55815248 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/3/z.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on z then move to the next block on the grid +scoreboard players operation #raycast.lz bs.data += #raycast.dz bs.data +$execute positioned ~ ~ ~$(sz) run return run function bs.raycast:recurse/3/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/4/next.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/4/next.mcfunction new file mode 100644 index 0000000000..d434fa6f77 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/4/next.mcfunction @@ -0,0 +1,24 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# check block and entity collisions +$execute unless block ~ ~ ~ $(ignored_blocks) run function bs.raycast:check/block/any with storage bs:data raycast +$execute if score #raycast.max_distance bs.data matches 1.. as @e[type=!$(ignored_entities),tag=$(entities),predicate=!bs.raycast:internal/checked,dx=0,sort=nearest] run function bs.raycast:check/entity/any +execute if score #raycast.max_distance bs.data matches 1.. if score $raycast.distance bs.lambda <= #raycast.lx bs.data if score $raycast.distance bs.lambda <= #raycast.ly bs.data if score $raycast.distance bs.lambda <= #raycast.lz bs.data run function bs.raycast:collide/any + +# advance on the grid by the shortest length +execute if score #raycast.lx bs.data <= #raycast.ly bs.data if score #raycast.lx bs.data <= #raycast.lz bs.data if score #raycast.lx bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/4/x with storage bs:data raycast +execute if score #raycast.ly bs.data <= #raycast.lz bs.data if score #raycast.ly bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/4/y with storage bs:data raycast +execute if score #raycast.lz bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/4/z with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/4/x.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/4/x.mcfunction new file mode 100644 index 0000000000..0aba5f7758 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/4/x.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on x then move to the next block on the grid +scoreboard players operation #raycast.lx bs.data += #raycast.dx bs.data +$execute positioned ~$(sx) ~ ~ run return run function bs.raycast:recurse/4/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/4/y.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/4/y.mcfunction new file mode 100644 index 0000000000..62c2078cd1 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/4/y.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on y then move to the next block on the grid +scoreboard players operation #raycast.ly bs.data += #raycast.dy bs.data +$execute positioned ~ ~$(sy) ~ run return run function bs.raycast:recurse/4/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/4/z.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/4/z.mcfunction new file mode 100644 index 0000000000..e27a2a28c4 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/4/z.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on z then move to the next block on the grid +scoreboard players operation #raycast.lz bs.data += #raycast.dz bs.data +$execute positioned ~ ~ ~$(sz) run return run function bs.raycast:recurse/4/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/5/next.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/5/next.mcfunction new file mode 100644 index 0000000000..12ea938933 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/5/next.mcfunction @@ -0,0 +1,25 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# check block, entity, and custom entity collisions +$execute unless block ~ ~ ~ $(ignored_blocks) run function bs.raycast:check/block/any with storage bs:data raycast +$execute if score #raycast.max_distance bs.data matches 1.. as @e[tag=bs.hitbox.custom,tag=$(entities),predicate=!bs.raycast:internal/checked,distance=..24,sort=nearest] run function bs.raycast:check/entity/any +$execute if score #raycast.max_distance bs.data matches 1.. as @e[type=!$(ignored_entities),tag=$(entities),predicate=!bs.raycast:internal/checked,dx=0,sort=nearest] run function bs.raycast:check/entity/any +execute if score #raycast.max_distance bs.data matches 1.. if score $raycast.distance bs.lambda <= #raycast.lx bs.data if score $raycast.distance bs.lambda <= #raycast.ly bs.data if score $raycast.distance bs.lambda <= #raycast.lz bs.data run function bs.raycast:collide/any + +# advance on the grid by the shortest length +execute if score #raycast.lx bs.data <= #raycast.ly bs.data if score #raycast.lx bs.data <= #raycast.lz bs.data if score #raycast.lx bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/5/x with storage bs:data raycast +execute if score #raycast.ly bs.data <= #raycast.lz bs.data if score #raycast.ly bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/5/y with storage bs:data raycast +execute if score #raycast.lz bs.data <= #raycast.max_distance bs.data run return run function bs.raycast:recurse/5/z with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/5/x.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/5/x.mcfunction new file mode 100644 index 0000000000..0a083b609f --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/5/x.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on x then move to the next block on the grid +scoreboard players operation #raycast.lx bs.data += #raycast.dx bs.data +$execute positioned ~$(sx) ~ ~ run return run function bs.raycast:recurse/5/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/5/y.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/5/y.mcfunction new file mode 100644 index 0000000000..cc4126d2ce --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/5/y.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on y then move to the next block on the grid +scoreboard players operation #raycast.ly bs.data += #raycast.dy bs.data +$execute positioned ~ ~$(sy) ~ run return run function bs.raycast:recurse/5/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/5/z.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/5/z.mcfunction new file mode 100644 index 0000000000..0fc4134d41 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/5/z.mcfunction @@ -0,0 +1,18 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +# increment length by delta on z then move to the next block on the grid +scoreboard players operation #raycast.lz bs.data += #raycast.dz bs.data +$execute positioned ~ ~ ~$(sz) run return run function bs.raycast:recurse/5/next with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/recurse/init.mcfunction b/modules/bs.raycast/data/bs.raycast/function/recurse/init.mcfunction index 37ddfdee2b..9739f97297 100644 --- a/modules/bs.raycast/data/bs.raycast/function/recurse/init.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/recurse/init.mcfunction @@ -47,14 +47,13 @@ scoreboard players operation #raycast.ly bs.data /= #raycast.uy bs.data scoreboard players operation #raycast.lz bs.data /= #raycast.uz bs.data # run the recursion loop -scoreboard players set @s bs.tmin 2147483647 -# @deprecated hitbox_shape (update following lines in in 4.0.0) +# @deprecated hitbox_shape, "collision" and "interaction" (update following lines in 4.0.0) +scoreboard players set @s bs.toi 2147483647 execute if data storage bs:data raycast{blocks:1b} run data modify storage bs:data raycast.blocks set from storage bs:data raycast.hitbox_shape execute if data storage bs:data raycast{blocks:1b} run data modify storage bs:data raycast.blocks set value "interaction" -execute if data storage bs:data raycast{blocks:"collision"} run data modify storage bs:data raycast.blocks set value "function #bs.hitbox:get_block_collision" -execute if data storage bs:data raycast{blocks:"interaction"} run data modify storage bs:data raycast.blocks set value "function #bs.hitbox:get_block_shape" +execute if data storage bs:data raycast{blocks:"collision"} run data modify storage bs:data raycast.blocks set value "function #bs.hitbox:callback/get_block_collision" +execute if data storage bs:data raycast{blocks:"interaction"} run data modify storage bs:data raycast.blocks set value "function #bs.hitbox:callback/get_block_shape" execute if data storage bs:data raycast{entities:1b} run data modify storage bs:data raycast.entities set value "!bs.raycast.omit" -execute unless data storage bs:data raycast{entities:0b} run function bs.raycast:check/entities with storage bs:data raycast -execute align xyz run function bs.raycast:recurse/next with storage bs:data raycast +$execute align xyz run function bs.raycast:recurse/$(y)/next with storage bs:data raycast tp @s ~ -100000 ~ kill @s diff --git a/modules/bs.raycast/data/bs.raycast/function/run.mcfunction b/modules/bs.raycast/data/bs.raycast/function/run.mcfunction index 06072c779f..5e0dfcb52c 100644 --- a/modules/bs.raycast/data/bs.raycast/function/run.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/run.mcfunction @@ -13,12 +13,29 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -scoreboard players set @s bs.tmin 2147483647 -execute store result score $raycast.piercing bs.lambda run data get storage bs:data raycast.piercing +execute store result score #raycast.bpiercing bs.data store result score #raycast.epiercing bs.data \ + run data get storage bs:data raycast.piercing 1 +execute if score #raycast.bpiercing bs.data matches 0 store result score #raycast.bpiercing bs.data \ + run data get storage bs:data raycast.piercing.blocks 1 +execute if score #raycast.epiercing bs.data matches 0 store result score #raycast.epiercing bs.data \ + run data get storage bs:data raycast.piercing.entities 1 +scoreboard players add #raycast.bpiercing bs.data 1 +scoreboard players add #raycast.epiercing bs.data 1 + +execute store result score #raycast.btoi bs.data store result score #raycast.etoi bs.data \ + run scoreboard players set $raycast.distance bs.lambda 2147483647 +execute store result score #i bs.ctx run scoreboard players set $raycast.pierce_distance bs.lambda 0 execute store result score #raycast.max_distance bs.data run data get storage bs:data raycast.max_distance 1000 -execute store result score #raycast.btmin bs.data store result score #raycast.etmin bs.data run scoreboard players set #raycast.tmin bs.data 2147483647 -data modify storage bs:lambda raycast set value {distance:0d,hit_normal:[0,0,0]} -execute positioned ^ ^ ^ summon minecraft:marker run function bs.raycast:recurse/init + +# @deprecated remove out in v4.0.0 +data remove storage bs:out raycast +data remove storage bs:lambda raycast +execute unless data storage bs:data raycast{blocks:0b} run scoreboard players add #i bs.ctx 2 +execute unless data storage bs:data raycast{entities:0b} run scoreboard players add #i bs.ctx 3 +execute unless data storage bs:data raycast{entities:0b} if entity @e[tag=bs.hitbox.custom,distance=..255,limit=1] run scoreboard players add #i bs.ctx 1 +execute store result storage bs:ctx y int 1 run scoreboard players remove #i bs.ctx 1 +execute positioned ^ ^ ^ summon minecraft:marker run function bs.raycast:recurse/init with storage bs:ctx +execute unless data storage bs:data raycast{entities:0b} run scoreboard players reset @e[distance=..255,scores={bs.toi=0..}] bs.toi data modify storage bs:out raycast set from storage bs:lambda raycast -scoreboard players reset @e[distance=..255,scores={bs.tmin=0..}] bs.tmin -return run execute unless score #raycast.tmin bs.data matches 2147483647 +execute if score $raycast.distance bs.lambda matches 2147483647 run return fail +return 1 diff --git a/modules/bs.raycast/data/bs.raycast/function/utils/get_hit_normal.mcfunction b/modules/bs.raycast/data/bs.raycast/function/utils/get_hit_normal.mcfunction new file mode 100644 index 0000000000..574d3ff696 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/utils/get_hit_normal.mcfunction @@ -0,0 +1,21 @@ +# ------------------------------------------------------------------------------------------------------------ +# 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. +# ------------------------------------------------------------------------------------------------------------ + +execute if score $raycast.hit_face bs.lambda matches 5 run data modify storage bs:lambda raycast.hit_normal set value [1,0,0] +execute if score $raycast.hit_face bs.lambda matches 4 run data modify storage bs:lambda raycast.hit_normal set value [-1,0,0] +execute if score $raycast.hit_face bs.lambda matches 3 run data modify storage bs:lambda raycast.hit_normal set value [0,0,1] +execute if score $raycast.hit_face bs.lambda matches 2 run data modify storage bs:lambda raycast.hit_normal set value [0,0,-1] +execute if score $raycast.hit_face bs.lambda matches 1 run data modify storage bs:lambda raycast.hit_normal set value [0,1,0] +execute if score $raycast.hit_face bs.lambda matches 0 run data modify storage bs:lambda raycast.hit_normal set value [0,-1,0] diff --git a/modules/bs.raycast/data/bs.raycast/function/utils/get_hit_point.mcfunction b/modules/bs.raycast/data/bs.raycast/function/utils/get_hit_point.mcfunction index 7a63b8270b..edbfc17191 100644 --- a/modules/bs.raycast/data/bs.raycast/function/utils/get_hit_point.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/utils/get_hit_point.mcfunction @@ -13,5 +13,6 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -$tp @s ^ ^ ^$(distance) +function bs.raycast:utils/tp_hit_point with storage bs:lambda raycast data modify storage bs:lambda raycast.hit_point set from entity @s Pos +tp @s ~ ~ ~ diff --git a/modules/bs.raycast/data/bs.raycast/function/collide/block/at_block.mcfunction b/modules/bs.raycast/data/bs.raycast/function/utils/get_targeted_block.mcfunction similarity index 70% rename from modules/bs.raycast/data/bs.raycast/function/collide/block/at_block.mcfunction rename to modules/bs.raycast/data/bs.raycast/function/utils/get_targeted_block.mcfunction index e9c0775af1..324bc433ae 100644 --- a/modules/bs.raycast/data/bs.raycast/function/collide/block/at_block.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/utils/get_targeted_block.mcfunction @@ -13,8 +13,6 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ -scoreboard players set #raycast.btmin bs.data 2147483647 - scoreboard players operation #x bs.ctx = #raycast.lx bs.data scoreboard players operation #x bs.ctx /= #raycast.dx bs.data scoreboard players operation #y bs.ctx = #raycast.ly bs.data @@ -29,11 +27,3 @@ data modify storage bs:lambda raycast.targeted_block set value [0,0,0] execute store result storage bs:lambda raycast.targeted_block[0] int 1 run scoreboard players operation #x bs.ctx += #raycast.x bs.data execute store result storage bs:lambda raycast.targeted_block[1] int 1 run scoreboard players operation #y bs.ctx += #raycast.y bs.data execute store result storage bs:lambda raycast.targeted_block[2] int 1 run scoreboard players operation #z bs.ctx += #raycast.z bs.data - -data modify storage bs:lambda raycast.hit_normal set value [0,0,0] -execute if score #raycast.norm bs.data matches 0 store result storage bs:lambda raycast.hit_normal[0] int -1 run data get storage bs:data raycast.sx -execute if score #raycast.norm bs.data matches 1 store result storage bs:lambda raycast.hit_normal[1] int -1 run data get storage bs:data raycast.sy -execute if score #raycast.norm bs.data matches 2 store result storage bs:lambda raycast.hit_normal[2] int -1 run data get storage bs:data raycast.sz - -execute positioned as @s run function bs.raycast:collide/block/at_origin -execute if data storage bs:data raycast.on_targeted_block run function bs.raycast:utils/on_targeted_block with storage bs:data raycast diff --git a/modules/bs.raycast/data/bs.raycast/function/utils/is_near_ray.mcfunction b/modules/bs.raycast/data/bs.raycast/function/utils/is_near_ray.mcfunction deleted file mode 100644 index 6658e44fbe..0000000000 --- a/modules/bs.raycast/data/bs.raycast/function/utils/is_near_ray.mcfunction +++ /dev/null @@ -1,20 +0,0 @@ -# ------------------------------------------------------------------------------------------------------------ -# 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. -# ------------------------------------------------------------------------------------------------------------ - -execute positioned ^1010 ^ ^ unless entity @s[distance=..1000] \ - positioned ^-2020 ^ ^ unless entity @s[distance=..1000] \ - positioned ^1010 ^1010 ^ unless entity @s[distance=..1000] \ - positioned ^ ^-2030 ^ unless entity @s[distance=..1000] \ - run return 1 diff --git a/modules/bs.raycast/data/bs.raycast/function/utils/tp_hit_point.mcfunction b/modules/bs.raycast/data/bs.raycast/function/utils/tp_hit_point.mcfunction new file mode 100644 index 0000000000..88a6098580 --- /dev/null +++ b/modules/bs.raycast/data/bs.raycast/function/utils/tp_hit_point.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. +# ------------------------------------------------------------------------------------------------------------ + +$tp @s ^ ^ ^$(distance) diff --git a/modules/bs.raycast/data/bs.raycast/function/with.mcfunction b/modules/bs.raycast/data/bs.raycast/function/with.mcfunction index 27af9d6abc..ba82a9f2ee 100644 --- a/modules/bs.raycast/data/bs.raycast/function/with.mcfunction +++ b/modules/bs.raycast/data/bs.raycast/function/with.mcfunction @@ -13,6 +13,7 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ +# @deprecated (set data to false in 4.0.0) data modify storage bs:data raycast set value { \ sx: 1, \ sy: 1, \ @@ -22,5 +23,6 @@ data modify storage bs:data raycast set value { \ max_distance: 16.0, \ ignored_blocks: "#bs.hitbox:intangible", \ ignored_entities: "#bs.hitbox:intangible", \ + data: {hit_point:1b,hit_normal:1b,targeted_block:1b,targeted_entity:1b}, \ } $data modify storage bs:data raycast merge value $(with) diff --git a/modules/bs.raycast/data/bs.raycast/predicate/checked.json b/modules/bs.raycast/data/bs.raycast/predicate/internal/checked.json similarity index 86% rename from modules/bs.raycast/data/bs.raycast/predicate/checked.json rename to modules/bs.raycast/data/bs.raycast/predicate/internal/checked.json index fc01049eca..67db5d5d2f 100644 --- a/modules/bs.raycast/data/bs.raycast/predicate/checked.json +++ b/modules/bs.raycast/data/bs.raycast/predicate/internal/checked.json @@ -2,7 +2,7 @@ "condition": "minecraft:entity_scores", "entity": "this", "scores": { - "bs.tmin": { + "bs.toi": { "min": 0 } } diff --git a/modules/bs.raycast/data/bs.raycast/predicate/collide.json b/modules/bs.raycast/data/bs.raycast/predicate/internal/collide.json similarity index 69% rename from modules/bs.raycast/data/bs.raycast/predicate/collide.json rename to modules/bs.raycast/data/bs.raycast/predicate/internal/collide.json index 4d5ba53ff5..4004133e0f 100644 --- a/modules/bs.raycast/data/bs.raycast/predicate/collide.json +++ b/modules/bs.raycast/data/bs.raycast/predicate/internal/collide.json @@ -2,22 +2,22 @@ "condition": "minecraft:entity_scores", "entity": "this", "scores": { - "bs.tmin": { + "bs.toi": { "min": { "type": "minecraft:score", "target": { "type": "minecraft:fixed", - "name": "#raycast.tmin" + "name": "$raycast.distance" }, - "score": "bs.data" + "score": "bs.lambda" }, "max": { "type": "minecraft:score", "target": { "type": "minecraft:fixed", - "name": "#raycast.tmin" + "name": "$raycast.distance" }, - "score": "bs.data" + "score": "bs.lambda" } } } diff --git a/modules/bs.raycast/data/bs.raycast/tags/function/run.json b/modules/bs.raycast/data/bs.raycast/tags/function/run.json index 8ab6504d34..62dd282f26 100644 --- a/modules/bs.raycast/data/bs.raycast/tags/function/run.json +++ b/modules/bs.raycast/data/bs.raycast/tags/function/run.json @@ -1,7 +1,7 @@ { "__bookshelf__": { "feature": true, - "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/raycast.html#run-the-raycast", + "documentation": "https://docs.mcbookshelf.dev/en/latest/modules/raycast.html#run", "authors": [ "Aksiome" ], @@ -10,8 +10,8 @@ "minecraft_version": "1.20.2" }, "updated": { - "date": "2025/08/27", - "minecraft_version": "1.21.8" + "date": "2025/11/09", + "minecraft_version": "1.21.10" } }, "values": [ diff --git a/modules/bs.view/data/bs.view/function/__load__.mcfunction b/modules/bs.view/data/bs.view/function/__load__.mcfunction index bf049c8cc6..4a284a6028 100644 --- a/modules/bs.view/data/bs.view/function/__load__.mcfunction +++ b/modules/bs.view/data/bs.view/function/__load__.mcfunction @@ -17,4 +17,7 @@ forceload add -30000000 1600 execute unless entity B5-0-0-0-1 run summon minecraft:marker -30000000 0 1600 {UUID:[I;181,0,0,1],Tags:["bs.entity","bs.persistent","smithed.entity","smithed.strict"]} execute unless entity B5-0-0-0-2 run summon minecraft:text_display -30000000 0 1600 {UUID:[I;181,0,0,2],Tags:["bs.entity","bs.persistent","smithed.entity","smithed.strict"],view_range:0f,alignment:"center"} +scoreboard objectives add bs.const dummy [{text:"BS ",color:"dark_gray"},{text:"Constants",color:"aqua"}] scoreboard objectives add bs.data dummy [{text:"BS ",color:"dark_gray"},{text:"Data",color:"aqua"}] + +scoreboard players set 2 bs.const 2 diff --git a/modules/bs.view/data/bs.view/function/__unload__.mcfunction b/modules/bs.view/data/bs.view/function/__unload__.mcfunction index aa4d4c4517..844ab60670 100644 --- a/modules/bs.view/data/bs.view/function/__unload__.mcfunction +++ b/modules/bs.view/data/bs.view/function/__unload__.mcfunction @@ -17,6 +17,7 @@ kill B5-0-0-0-1 kill B5-0-0-0-2 forceload remove -30000000 1600 +scoreboard objectives remove bs.const scoreboard objectives remove bs.data data remove storage bs:in view diff --git a/modules/bs.view/data/bs.view/function/aimed_block/with.mcfunction b/modules/bs.view/data/bs.view/function/aimed_block/with.mcfunction index 27af9d6abc..f5bf15ab52 100644 --- a/modules/bs.view/data/bs.view/function/aimed_block/with.mcfunction +++ b/modules/bs.view/data/bs.view/function/aimed_block/with.mcfunction @@ -22,5 +22,6 @@ data modify storage bs:data raycast set value { \ max_distance: 16.0, \ ignored_blocks: "#bs.hitbox:intangible", \ ignored_entities: "#bs.hitbox:intangible", \ + data: {hit_point:0b,hit_normal:0b,targeted_block:0b,targeted_entity:0b}, \ } $data modify storage bs:data raycast merge value $(with) diff --git a/modules/bs.view/data/bs.view/function/aimed_entity/with.mcfunction b/modules/bs.view/data/bs.view/function/aimed_entity/with.mcfunction index 8ce3b98a68..b54af5087a 100644 --- a/modules/bs.view/data/bs.view/function/aimed_entity/with.mcfunction +++ b/modules/bs.view/data/bs.view/function/aimed_entity/with.mcfunction @@ -22,5 +22,6 @@ data modify storage bs:data raycast set value { \ max_distance: 16.0, \ ignored_blocks: "#bs.hitbox:intangible", \ ignored_entities: "#bs.hitbox:intangible", \ + data: {hit_point:0b,hit_normal:0b,targeted_block:0b,targeted_entity:0b}, \ } $data modify storage bs:data raycast merge value $(with) diff --git a/modules/bs.view/data/bs.view/function/aimed_point/with.mcfunction b/modules/bs.view/data/bs.view/function/aimed_point/with.mcfunction index 8ce3b98a68..b54af5087a 100644 --- a/modules/bs.view/data/bs.view/function/aimed_point/with.mcfunction +++ b/modules/bs.view/data/bs.view/function/aimed_point/with.mcfunction @@ -22,5 +22,6 @@ data modify storage bs:data raycast set value { \ max_distance: 16.0, \ ignored_blocks: "#bs.hitbox:intangible", \ ignored_entities: "#bs.hitbox:intangible", \ + data: {hit_point:0b,hit_normal:0b,targeted_block:0b,targeted_entity:0b}, \ } $data modify storage bs:data raycast merge value $(with) diff --git a/modules/bs.view/data/bs.view/function/block_placement/displace.mcfunction b/modules/bs.view/data/bs.view/function/block_placement/displace.mcfunction index 4aaadf3547..d76c9cf706 100644 --- a/modules/bs.view/data/bs.view/function/block_placement/displace.mcfunction +++ b/modules/bs.view/data/bs.view/function/block_placement/displace.mcfunction @@ -13,6 +13,9 @@ # For more details, refer to the MPL v2.0. # ------------------------------------------------------------------------------------------------------------ +scoreboard players operation $raycast.hit_flag bs.lambda %= 2 bs.const +execute if score $raycast.hit_flag bs.lambda matches 0 run return run scoreboard players add $raycast.piercing bs.lambda 1 + data modify storage bs:data view.block_placement.x set from storage bs:lambda raycast.hit_normal[0] data modify storage bs:data view.block_placement.y set from storage bs:lambda raycast.hit_normal[1] data modify storage bs:data view.block_placement.z set from storage bs:lambda raycast.hit_normal[2] diff --git a/modules/bs.view/data/bs.view/function/block_placement/with.mcfunction b/modules/bs.view/data/bs.view/function/block_placement/with.mcfunction index 48d491122a..dee1285a7a 100644 --- a/modules/bs.view/data/bs.view/function/block_placement/with.mcfunction +++ b/modules/bs.view/data/bs.view/function/block_placement/with.mcfunction @@ -17,11 +17,12 @@ data modify storage bs:data raycast set value { \ sx: 1, \ sy: 1, \ sz: 1, \ - blocks: true, \ + blocks: "function #bs.hitbox:callback/get_block_placement", \ entities: false, \ max_distance: 16.0, \ ignored_blocks: "#bs.hitbox:intangible", \ ignored_entities: "#bs.hitbox:intangible", \ on_targeted_block: "function bs.view:block_placement/displace", \ + data: {hit_point:0b,hit_normal:1b,targeted_block:0b,targeted_entity:0b}, \ } $data modify storage bs:data raycast merge value $(with) diff --git a/modules/bs.view/data/bs.view/function/can_see_ata/with.mcfunction b/modules/bs.view/data/bs.view/function/can_see_ata/with.mcfunction index 8eb2b4c032..d478c381df 100644 --- a/modules/bs.view/data/bs.view/function/can_see_ata/with.mcfunction +++ b/modules/bs.view/data/bs.view/function/can_see_ata/with.mcfunction @@ -21,5 +21,6 @@ data modify storage bs:data raycast set value { \ entities: false, \ ignored_blocks: "#bs.view:can_see_through", \ ignored_entities: "#bs.hitbox:intangible", \ + data: {hit_point:0b,hit_normal:0b,targeted_block:0b,targeted_entity:0b}, \ } $data modify storage bs:data raycast merge value $(with)