Skip to content

Commit

Permalink
hibtox detection is no longer ray facing dependent, now it's vector d…
Browse files Browse the repository at this point in the history
…ependent
  • Loading branch information
mattcarter11 committed Sep 7, 2024
1 parent 849565e commit ad87eeb
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 32 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Intro
Minecraft Ray Collision Detector is a super precise raycast system in vanilla minecraft! This datapack solved the raycast problem perfectly with minimal command cost. It defines the hitbox of most blocks and does some calculations to judge which surface will be touched.

Current datapack version: 3.0
Current datapack version: 3.1

Supported minecraft version:
- Release 2.7.2: 1.16, 1.17, 1.18, 1.19, 1.20,
- Release 3.0: 1.21
- Release 3.1: 1.21

# How to use

Expand All @@ -19,13 +19,13 @@ Supported minecraft version:

## Advanced ray behaviour
- **Pass any block a player can:** tag the ray with `mrcd_bullet`.
- **Hit the first entity it finds:**: tag the ray with `mrcd_entity` and rotate it facing the motion direction.
- **Hit the first entity it finds:**: tag the ray with `mrcd_entity`.
- If it thouches an entity, the ray will stop there and get the tag `mrcd_touch_entity`. The touched entity will be tagged `mrcd_target_entity`.
- Note that some entities like player and projectiles are ignored by default. You can remove them by editing the entity types tag `#mrcd:ignore`.
- **Hit the first specific entity or group of entities:** tag the ray with `mrcd_entity_targeted`, rotate it facing the motion direction** and tag the target/s with `mrcd_target`.
- **Hit the first specific entity or group of entities:** tag the ray with `mrcd_entity_targeted` and tag the target/s with `mrcd_target`.
- If it thouches an entity, the ray will stop there and get the tag `mrcd_touch_entity`. The touched entity will be tagged `mrcd_target_entity`. Any non `mrcd_target` tagged entity will be ignored and the ray will pass through.
- This method can target any entity, even those that are in the `#mrcd:ignore` tag list. Also, you can tag an entity with `mrcd_ignore` to also be ignored.
- **Hit multiple entities (don't stop after one found):** settup the ray as a `mrcd_entity` or `mrcd_entity_targeted`, add the tag `mrcd_entity_bullet` and rotate the it facing the motion direction.
- **Hit multiple entities (don't stop after one found):** settup the ray as a `mrcd_entity` or `mrcd_entity_targeted` and add the tag `mrcd_entity_bullet`.
- If it thouches an entity, the ray will continue but get the tag `mrcd_touch_entity`. The touched entity will be tagged `mrcd_target_entity`.

In summary, tags can be combined following this strucuture: <block_handling>,<entity_handling1>,<entity_extra>
Expand Down Expand Up @@ -351,4 +351,7 @@ These blocks listed below are supported in is datapack. Please post an issue if
* Added nether_portal
* Fixes
* Fixed chains
* v3.1
* Updates
* Hitbox collision is no longer dependant on the ray (entity) facing direction. Now it's dependant on the ray vector
</details>
8 changes: 4 additions & 4 deletions data/mrcd/function/private/recurse.mcfunction
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ scoreboard players add n_recursion mrcd_system 1
# tellraw @a ["block (",{"score":{"name":"#block_x","objective":"mrcd_system"}},", ",{"score":{"name":"#block_y","objective":"mrcd_system"}},", ",{"score":{"name":"#block_z","objective":"mrcd_system"}}, ") (x, y, z)"]
# tellraw @a ["block_corner (",{"score":{"name":"#block_corner_x","objective":"mrcd_system"}},", ",{"score":{"name":"#block_corner_y","objective":"mrcd_system"}},", ",{"score":{"name":"#block_corner_z","objective":"mrcd_system"}}, ") (x, y, z)"]

# particle end_rod ~ ~ ~ 0 0 0 0.01 1 force
# execute at @s run particle end_rod ~ ~ ~ 0 0 0 0 1 force
# particle wax_off ~ ~ ~ 0 0 0 0.01 1 force
# execute at @s run particle wax_on ~ ~ ~ 0 0 0 0.01 1 force


# === Block Collision Test ===
Expand Down Expand Up @@ -42,8 +42,8 @@ execute if score #abs_total_x mrcd_system >= #abs_traveled_x mrcd_system if scor


# === Entity Collision Test ===
# If is mrcd_entity or mrcd_entity_targeted and there is a entity hitbox in this block
execute if score #detect_entity mrcd_system matches 1 align xyz run function mrcd:private/recurse/entity_collision/main
# If is mrcd_entity or mrcd_entity_targeted
execute if score #detect_entity mrcd_system matches 1.. align xyz run function mrcd:private/recurse/entity_collision/main


# === Debug ===
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
tag @s add mrcd_ignore
tag @s add mrcd_block_end
tag @s add mrcd_block_marker

# Set marker position: depends if reached ray total or colided with a block
execute if score #total_before_collision mrcd_system matches 1 run function mrcd:private/recurse/entity_collision/block_end_marker/total
execute if score #total_before_collision mrcd_system matches 0 run function mrcd:private/recurse/entity_collision/block_end_marker/collision
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
tag @s add mrcd_ignore
tag @s add mrcd_block_start
tag @s add mrcd_block_marker

scoreboard players operation #temp_x mrcd_system = #block_x mrcd_system
scoreboard players operation #temp_y mrcd_system = #block_y mrcd_system
scoreboard players operation #temp_z mrcd_system = #block_z mrcd_system

scoreboard players operation #temp_x mrcd_system += #block_corner_x mrcd_system
scoreboard players operation #temp_y mrcd_system += #block_corner_y mrcd_system
scoreboard players operation #temp_z mrcd_system += #block_corner_z mrcd_system

execute store result entity @s Pos[0] double 0.001 run scoreboard players get #temp_x mrcd_system
execute store result entity @s Pos[1] double 0.001 run scoreboard players get #temp_y mrcd_system
execute store result entity @s Pos[2] double 0.001 run scoreboard players get #temp_z mrcd_system

execute at @s run tp @s ~ ~ ~ facing entity @n[type=area_effect_cloud,tag=mrcd_block_end]
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Tag collided entities
execute if entity @s[tag=mrcd_entity,tag=!mrcd_entity_targeted] positioned ~-.05 ~-.05 ~-.05 as @e[type=!#mrcd:ignore,tag=!mrcd_ignore,dx=0] positioned ~-.9 ~-.9 ~-.9 run tag @s[dx=0] add mrcd_target_entity
execute if entity @s[tag=mrcd_entity_targeted] positioned ~-.05 ~-.05 ~-.05 as @e[tag=mrcd_target,tag=!mrcd_ignore,dx=0] positioned ~-.9 ~-.9 ~-.9 run tag @s[dx=0] add mrcd_target_entity
execute if score #detect_entity mrcd_system matches 1 positioned ~-.05 ~-.05 ~-.05 as @e[type=!#mrcd:ignore,tag=!mrcd_ignore,dx=0] positioned ~-.9 ~-.9 ~-.9 run tag @s[dx=0] add mrcd_target_entity
execute if score #detect_entity mrcd_system matches 2 positioned ~-.05 ~-.05 ~-.05 as @e[tag=mrcd_target,tag=!mrcd_ignore,dx=0] positioned ~-.9 ~-.9 ~-.9 run tag @s[dx=0] add mrcd_target_entity

# Debug
# particle end_rod ~ ~ ~ 0 0 0 0 1
# particle wax_off ~ ~ ~ 0 0 0 0 1

# Loop
scoreboard players add #steps mrcd_system 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
execute if entity @s[tag=mrcd_entity,tag=!mrcd_entity_targeted] run return run execute if entity @e[type=!#mrcd:ignore,tag=!mrcd_ignore,dx=0,limit=1] run function mrcd:private/recurse/entity_collision/main_
execute if entity @s[tag=mrcd_entity_targeted] run return run execute if entity @e[tag=mrcd_target,tag=!mrcd_ignore,dx=0,limit=1] run function mrcd:private/recurse/entity_collision/main_
# If there is a entity hitbox in this block (and this hitbox was not previously considered in the iteration
execute if entity @s[tag=!mrcd_entity_targeted] run return run execute if entity @e[type=!#mrcd:ignore,tag=!mrcd_ignore,tag=!mrcd_target_entity,dx=0,limit=1] run function mrcd:private/recurse/entity_collision/main_
execute if entity @s[tag=mrcd_entity_targeted] run return run execute if entity @e[tag=mrcd_target,tag=!mrcd_ignore,tag=!mrcd_target_entity,dx=0,limit=1] run function mrcd:private/recurse/entity_collision/main_
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
# Summon finish point marker at block edge (collision or total)
summon area_effect_cloud ~ ~ ~ {Tags:["mrcd_block_end","mrcd_ignore"]}
execute if score #total_before_collision mrcd_system matches 1 as @e[type=area_effect_cloud,tag=mrcd_block_end,limit=1] run function mrcd:private/recurse/entity_collision/marker/total
execute if score #total_before_collision mrcd_system matches 0 as @e[type=area_effect_cloud,tag=mrcd_block_end,limit=1] run function mrcd:private/recurse/entity_collision/marker/collision
# Summon finish position marker at block edge
execute summon area_effect_cloud run function mrcd:private/recurse/entity_collision/block_end_marker/post_summon

# Tp @s to current block starting position
scoreboard players operation #temp_x mrcd_system = #block_x mrcd_system
scoreboard players operation #temp_y mrcd_system = #block_y mrcd_system
scoreboard players operation #temp_z mrcd_system = #block_z mrcd_system
# Summon starting position marker
execute summon area_effect_cloud run function mrcd:private/recurse/entity_collision/block_start_marker/post_summon

scoreboard players operation #temp_x mrcd_system += #block_corner_x mrcd_system
scoreboard players operation #temp_y mrcd_system += #block_corner_y mrcd_system
scoreboard players operation #temp_z mrcd_system += #block_corner_z mrcd_system
# Debug (show block where entity is found)
# particle wax_off ~ ~ ~ 0 0 0 0 1 force
# particle wax_off ~1 ~ ~ 0 0 0 0 1 force
# particle wax_off ~ ~1 ~ 0 0 0 0 1 force
# particle wax_off ~ ~ ~1 0 0 0 0 1 force
# particle wax_off ~1 ~1 ~ 0 0 0 0 1 force
# particle wax_off ~1 ~ ~1 0 0 0 0 1 force
# particle wax_off ~ ~1 ~1 0 0 0 0 1 force
# particle wax_off ~1 ~1 ~1 0 0 0 0 1 force

execute store result entity @s Pos[0] double 0.001 run scoreboard players get #temp_x mrcd_system
execute store result entity @s Pos[1] double 0.001 run scoreboard players get #temp_y mrcd_system
execute store result entity @s Pos[2] double 0.001 run scoreboard players get #temp_z mrcd_system
# execute at @e[type=area_effect_cloud,tag=mrcd_block_start,limit=1] run particle scrape ~ ~ ~ 0 0 0 0 1 force
# execute at @e[type=area_effect_cloud,tag=mrcd_block_end,limit=1] run particle wax_on ~ ~ ~ 0 0 0 0 1 force

# Iterate in small steps checking if entity is reached
scoreboard players set #steps mrcd_system 0
execute at @s run function mrcd:private/recurse/entity_collision/loop
execute as @e[type=area_effect_cloud,tag=mrcd_block_start,limit=1] at @s run function mrcd:private/recurse/entity_collision/loop

# If collision detected and is bullet
execute if entity @e[tag=mrcd_target_entity,limit=1] if entity @s[tag=!mrcd_entity_bullet] run function mrcd:private/recurse/entity_collision/not_bullet
execute if entity @e[tag=mrcd_target_entity,limit=1] run tag @s add mrcd_touch_entity

# Clean
kill @e[type=area_effect_cloud,tag=mrcd_block_end,limit=1]
kill @e[type=area_effect_cloud,tag=mrcd_block_marker]
5 changes: 3 additions & 2 deletions data/mrcd/function/ray_tick.mcfunction
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ scoreboard players set #target_y mrcd_system 0
scoreboard players set #target_z mrcd_system 0

# === Init flags ===
# if mrcd_entity or mrcd_entity_targeted = not(mrcd_entity and mrcd_entity_targeted)
execute store result score #detect_entity mrcd_system run execute unless entity @s[tag=!mrcd_entity,tag=!mrcd_entity_targeted]
scoreboard players set #detect_entity mrcd_system 0
execute if entity @s[tag=mrcd_entity] run scoreboard players set #detect_entity mrcd_system 1
execute if entity @s[tag=mrcd_entity_targeted] run scoreboard players set #detect_entity mrcd_system 2

# === Debug ===
# summon marker ~ ~ ~ {Tags:["at_target","init"]}
Expand Down

0 comments on commit ad87eeb

Please sign in to comment.