aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2025-03-16 13:41:17 -0500
committerGitHub <noreply@github.com>2025-03-16 13:41:17 -0500
commitb0bd992adcff71ee294dd05060e00e652f62a7b2 (patch)
tree0a36d8b37befbc75c8c65cc2c8779c3df66bd87b
parenta95408cbcc05b5bd04a084b0a286b571069206f6 (diff)
downloadazalea-drasl-b0bd992adcff71ee294dd05060e00e652f62a7b2.tar.xz
Fluid physics fixes (#210)
* start fixing code related to fluid physics * implement force_solid for blocks * afk pool test
-rwxr-xr-xazalea-block/src/behavior.rs1
-rwxr-xr-xazalea-block/src/generated.rs388
-rw-r--r--azalea-client/src/entity_query.rs4
-rw-r--r--azalea-client/src/plugins/brand.rs2
-rwxr-xr-xazalea-core/src/aabb.rs70
-rwxr-xr-xazalea-core/src/delta.rs4
-rwxr-xr-xazalea-core/src/direction.rs2
-rwxr-xr-xazalea-core/src/position.rs25
-rw-r--r--azalea-entity/src/lib.rs4
-rw-r--r--azalea-physics/src/clip.rs11
-rw-r--r--azalea-physics/src/collision/entity_collisions.rs97
-rw-r--r--azalea-physics/src/collision/mod.rs10
-rwxr-xr-xazalea-physics/src/collision/shape.rs11
-rw-r--r--azalea-physics/src/collision/world_collisions.rs182
-rw-r--r--azalea-physics/src/fluids.rs68
-rw-r--r--azalea-physics/src/lib.rs63
-rw-r--r--azalea-physics/src/travel.rs131
-rw-r--r--azalea-physics/tests/physics.rs138
-rwxr-xr-xazalea-protocol/src/connect.rs2
-rw-r--r--azalea/src/accept_resource_packs.rs6
-rwxr-xr-xcodegen/genblocks.py3
-rwxr-xr-xcodegen/lib/code/blocks.py13
-rwxr-xr-xcodegen/lib/extract.py23
-rwxr-xr-xcodegen/lib/mappings.py1
24 files changed, 873 insertions, 386 deletions
diff --git a/azalea-block/src/behavior.rs b/azalea-block/src/behavior.rs
index aeae8a74..37487b35 100755
--- a/azalea-block/src/behavior.rs
+++ b/azalea-block/src/behavior.rs
@@ -56,7 +56,6 @@ impl BlockBehavior {
self
}
- // TODO: currently unused
pub fn force_solid(mut self, force_solid: bool) -> Self {
self.force_solid = Some(force_solid);
self
diff --git a/azalea-block/src/generated.rs b/azalea-block/src/generated.rs
index de360550..afc131c3 100755
--- a/azalea-block/src/generated.rs
+++ b/azalea-block/src/generated.rs
@@ -2352,7 +2352,7 @@ make_block_states! {
"extended": Extended(false),
"facing": FacingCubic::North,
},
- cobweb => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.0, 4.0), {},
+ cobweb => BlockBehavior::new().requires_correct_tool_for_drops().strength(4.0, 4.0).force_solid(true), {},
short_grass => BlockBehavior::new(), {},
fern => BlockBehavior::new(), {},
dead_bush => BlockBehavior::new(), {},
@@ -2385,7 +2385,7 @@ make_block_states! {
green_wool => BlockBehavior::new().strength(0.8, 0.8), {},
red_wool => BlockBehavior::new().strength(0.8, 0.8), {},
black_wool => BlockBehavior::new().strength(0.8, 0.8), {},
- moving_piston => BlockBehavior::new().destroy_time(-1.0), {
+ moving_piston => BlockBehavior::new().destroy_time(-1.0).force_solid(true), {
"type": PistonType::Normal,
"facing": FacingCubic::North,
},
@@ -2474,43 +2474,43 @@ make_block_states! {
"facing": FacingCardinal::North,
"lit": Lit(false),
},
- oak_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ oak_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": OakSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- spruce_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ spruce_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": SpruceSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- birch_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ birch_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": BirchSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- acacia_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ acacia_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": AcaciaSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- cherry_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ cherry_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": CherrySignRotation::_0,
"waterlogged": Waterlogged(false),
},
- jungle_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ jungle_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": JungleSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- dark_oak_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ dark_oak_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": DarkOakSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- pale_oak_sign => BlockBehavior::new(), {
+ pale_oak_sign => BlockBehavior::new().force_solid(true), {
"rotation": PaleOakSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- mangrove_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ mangrove_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": MangroveSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- bamboo_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ bamboo_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": BambooSignRotation::_0,
"waterlogged": Waterlogged(false),
},
@@ -2521,7 +2521,7 @@ make_block_states! {
"open": Open(false),
"powered": Powered(false),
},
- ladder => BlockBehavior::new().strength(0.4, 0.4), {
+ ladder => BlockBehavior::new().strength(0.4, 0.4).force_solid(false), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
@@ -2535,151 +2535,151 @@ make_block_states! {
"shape": StairShape::Straight,
"waterlogged": Waterlogged(false),
},
- oak_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ oak_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- spruce_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ spruce_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- birch_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ birch_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- acacia_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ acacia_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- cherry_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ cherry_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- jungle_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ jungle_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- dark_oak_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ dark_oak_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- pale_oak_wall_sign => BlockBehavior::new(), {
+ pale_oak_wall_sign => BlockBehavior::new().force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- mangrove_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ mangrove_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- bamboo_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ bamboo_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- oak_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ oak_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": OakHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- spruce_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ spruce_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": SpruceHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- birch_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ birch_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": BirchHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- acacia_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ acacia_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": AcaciaHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- cherry_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ cherry_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": CherryHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- jungle_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ jungle_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": JungleHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- dark_oak_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ dark_oak_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": DarkOakHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- pale_oak_hanging_sign => BlockBehavior::new(), {
+ pale_oak_hanging_sign => BlockBehavior::new().force_solid(true), {
"attached": Attached(false),
"rotation": PaleOakHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- crimson_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ crimson_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": CrimsonHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- warped_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ warped_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": WarpedHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- mangrove_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ mangrove_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": MangroveHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- bamboo_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ bamboo_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"attached": Attached(false),
"rotation": BambooHangingSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- oak_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ oak_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- spruce_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ spruce_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- birch_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ birch_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- acacia_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ acacia_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- cherry_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ cherry_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- jungle_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ jungle_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- dark_oak_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ dark_oak_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- pale_oak_wall_hanging_sign => BlockBehavior::new(), {
+ pale_oak_wall_hanging_sign => BlockBehavior::new().force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- mangrove_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ mangrove_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- crimson_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ crimson_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- warped_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ warped_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- bamboo_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ bamboo_wall_hanging_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
@@ -2688,7 +2688,7 @@ make_block_states! {
"facing": FacingCardinal::North,
"powered": Powered(false),
},
- stone_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {
+ stone_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
iron_door => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 5.0), {
@@ -2698,34 +2698,34 @@ make_block_states! {
"open": Open(false),
"powered": Powered(false),
},
- oak_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ oak_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
- spruce_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ spruce_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
- birch_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ birch_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
- jungle_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ jungle_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
- acacia_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ acacia_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
- cherry_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ cherry_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
- dark_oak_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ dark_oak_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
- pale_oak_pressure_plate => BlockBehavior::new(), {
+ pale_oak_pressure_plate => BlockBehavior::new().force_solid(true), {
"powered": Powered(false),
},
- mangrove_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ mangrove_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
- bamboo_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ bamboo_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
redstone_ore => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 3.0), {
@@ -2746,7 +2746,7 @@ make_block_states! {
"facing": FacingCardinal::North,
"powered": Powered(false),
},
- snow => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.1, 0.1), {
+ snow => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.1, 0.1).force_solid(false), {
"layers": SnowLayers::_1,
},
ice => BlockBehavior::new().strength(0.5, 0.5).friction(0.98), {},
@@ -2761,7 +2761,7 @@ make_block_states! {
jukebox => BlockBehavior::new().strength(2.0, 6.0), {
"has_record": HasRecord(false),
},
- oak_fence => BlockBehavior::new().strength(2.0, 3.0), {
+ oak_fence => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"east": East(false),
"north": North(false),
"south": South(false),
@@ -2791,7 +2791,7 @@ make_block_states! {
jack_o_lantern => BlockBehavior::new().strength(1.0, 1.0), {
"facing": FacingCardinal::North,
},
- cake => BlockBehavior::new().strength(0.5, 0.5), {
+ cake => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"bites": CakeBites::_0,
},
repeater => BlockBehavior::new(), {
@@ -2929,7 +2929,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": West(false),
},
- chain => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0), {
+ chain => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 6.0).force_solid(true), {
"axis": Axis::Y,
"waterlogged": Waterlogged(false),
},
@@ -2979,7 +2979,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": West(false),
},
- oak_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ oak_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
@@ -3123,7 +3123,7 @@ make_block_states! {
"facing": FacingCubic::North,
},
beacon => BlockBehavior::new().strength(3.0, 3.0), {},
- cobblestone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
+ cobblestone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -3131,7 +3131,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- mossy_cobblestone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
+ mossy_cobblestone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -3294,10 +3294,10 @@ make_block_states! {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- light_weighted_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {
+ light_weighted_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5).force_solid(true), {
"power": LightWeightedPressurePlatePower::_0,
},
- heavy_weighted_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {
+ heavy_weighted_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5).force_solid(true), {
"power": HeavyWeightedPressurePlatePower::_0,
},
comparator => BlockBehavior::new(), {
@@ -3594,100 +3594,100 @@ make_block_states! {
large_fern => BlockBehavior::new(), {
"half": Half::Lower,
},
- white_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ white_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": WhiteBannerRotation::_0,
},
- orange_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ orange_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": OrangeBannerRotation::_0,
},
- magenta_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ magenta_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": MagentaBannerRotation::_0,
},
- light_blue_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ light_blue_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": LightBlueBannerRotation::_0,
},
- yellow_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ yellow_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": YellowBannerRotation::_0,
},
- lime_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ lime_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": LimeBannerRotation::_0,
},
- pink_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ pink_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": PinkBannerRotation::_0,
},
- gray_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ gray_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": GrayBannerRotation::_0,
},
- light_gray_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ light_gray_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": LightGrayBannerRotation::_0,
},
- cyan_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ cyan_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": CyanBannerRotation::_0,
},
- purple_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ purple_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": PurpleBannerRotation::_0,
},
- blue_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ blue_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": BlueBannerRotation::_0,
},
- brown_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ brown_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": BrownBannerRotation::_0,
},
- green_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ green_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": GreenBannerRotation::_0,
},
- red_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ red_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": RedBannerRotation::_0,
},
- black_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ black_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": BlackBannerRotation::_0,
},
- white_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ white_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- orange_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ orange_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- magenta_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ magenta_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- light_blue_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ light_blue_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- yellow_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ yellow_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- lime_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ lime_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- pink_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ pink_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- gray_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ gray_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- light_gray_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ light_gray_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- cyan_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ cyan_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- purple_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ purple_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- blue_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ blue_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- brown_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ brown_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- green_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ green_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- red_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ red_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
- black_wall_banner => BlockBehavior::new().strength(1.0, 1.0), {
+ black_wall_banner => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
},
red_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {},
@@ -3803,55 +3803,55 @@ make_block_states! {
smooth_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
smooth_quartz => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
smooth_red_sandstone => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {},
- spruce_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ spruce_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
"powered": Powered(false),
},
- birch_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ birch_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
"powered": Powered(false),
},
- jungle_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ jungle_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
"powered": Powered(false),
},
- acacia_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ acacia_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
"powered": Powered(false),
},
- cherry_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ cherry_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
"powered": Powered(false),
},
- dark_oak_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ dark_oak_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
"powered": Powered(false),
},
- pale_oak_fence_gate => BlockBehavior::new(), {
+ pale_oak_fence_gate => BlockBehavior::new().force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
"powered": Powered(false),
},
- mangrove_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ mangrove_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
"powered": Powered(false),
},
- bamboo_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ bamboo_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
@@ -3983,10 +3983,10 @@ make_block_states! {
"open": Open(false),
"powered": Powered(false),
},
- end_rod => BlockBehavior::new(), {
+ end_rod => BlockBehavior::new().force_solid(false), {
"facing": FacingCubic::Up,
},
- chorus_plant => BlockBehavior::new().strength(0.4, 0.4), {
+ chorus_plant => BlockBehavior::new().strength(0.4, 0.4).force_solid(false), {
"down": Down(false),
"east": East(false),
"north": North(false),
@@ -3994,7 +3994,7 @@ make_block_states! {
"up": Up(false),
"west": West(false),
},
- chorus_flower => BlockBehavior::new().strength(0.4, 0.4), {
+ chorus_flower => BlockBehavior::new().strength(0.4, 0.4).force_solid(false), {
"age": ChorusFlowerAge::_0,
},
purpur_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
@@ -4045,55 +4045,55 @@ make_block_states! {
"facing": FacingCubic::South,
"powered": Powered(false),
},
- shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- white_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ white_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- orange_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ orange_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- magenta_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ magenta_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- light_blue_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ light_blue_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- yellow_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ yellow_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- lime_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ lime_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- pink_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ pink_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- gray_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ gray_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- light_gray_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ light_gray_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- cyan_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ cyan_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- purple_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ purple_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- blue_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ blue_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- brown_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ brown_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- green_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ green_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- red_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ red_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
- black_shulker_box => BlockBehavior::new().strength(2.0, 2.0), {
+ black_shulker_box => BlockBehavior::new().strength(2.0, 2.0).force_solid(true), {
"facing": FacingCubic::Up,
},
white_glazed_terracotta => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.4, 1.4), {
@@ -4181,36 +4181,36 @@ make_block_states! {
},
kelp_plant => BlockBehavior::new(), {},
dried_kelp_block => BlockBehavior::new().strength(0.5, 2.5), {},
- turtle_egg => BlockBehavior::new().strength(0.5, 0.5), {
+ turtle_egg => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"eggs": TurtleEggEggs::_1,
"hatch": TurtleEggHatch::_0,
},
sniffer_egg => BlockBehavior::new().strength(0.5, 0.5), {
"hatch": SnifferEggHatch::_0,
},
- dead_tube_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
- dead_brain_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
- dead_bubble_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
- dead_fire_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
- dead_horn_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
+ dead_tube_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {},
+ dead_brain_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {},
+ dead_bubble_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {},
+ dead_fire_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {},
+ dead_horn_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {},
tube_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
brain_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
bubble_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
fire_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
horn_coral_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {},
- dead_tube_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_tube_coral => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
- dead_brain_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_brain_coral => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
- dead_bubble_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_bubble_coral => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
- dead_fire_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_fire_coral => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
- dead_horn_coral => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_horn_coral => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
tube_coral => BlockBehavior::new(), {
@@ -4228,19 +4228,19 @@ make_block_states! {
horn_coral => BlockBehavior::new(), {
"waterlogged": Waterlogged(true),
},
- dead_tube_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_tube_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
- dead_brain_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_brain_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
- dead_bubble_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_bubble_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
- dead_fire_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_fire_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
- dead_horn_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_horn_coral_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"waterlogged": Waterlogged(true),
},
tube_coral_fan => BlockBehavior::new(), {
@@ -4258,23 +4258,23 @@ make_block_states! {
horn_coral_fan => BlockBehavior::new(), {
"waterlogged": Waterlogged(true),
},
- dead_tube_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_tube_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(true),
},
- dead_brain_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_brain_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(true),
},
- dead_bubble_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_bubble_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(true),
},
- dead_fire_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_fire_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(true),
},
- dead_horn_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops(), {
+ dead_horn_coral_wall_fan => BlockBehavior::new().requires_correct_tool_for_drops().force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(true),
},
@@ -4303,11 +4303,11 @@ make_block_states! {
"waterlogged": Waterlogged(true),
},
blue_ice => BlockBehavior::new().strength(2.8, 2.8).friction(0.989), {},
- conduit => BlockBehavior::new().strength(3.0, 3.0), {
+ conduit => BlockBehavior::new().strength(3.0, 3.0).force_solid(true), {
"waterlogged": Waterlogged(true),
},
- bamboo_sapling => BlockBehavior::new().strength(1.0, 1.0), {},
- bamboo => BlockBehavior::new().strength(1.0, 1.0), {
+ bamboo_sapling => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {},
+ bamboo => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"age": BambooAge::_0,
"leaves": Leaves::None,
"stage": BambooStage::_0,
@@ -4454,7 +4454,7 @@ make_block_states! {
"type": Type::Bottom,
"waterlogged": Waterlogged(false),
},
- brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
+ brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4462,7 +4462,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- prismarine_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ prismarine_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4470,7 +4470,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- red_sandstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {
+ red_sandstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4478,7 +4478,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- mossy_stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ mossy_stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4486,7 +4486,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- granite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ granite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4494,7 +4494,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4502,7 +4502,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- mud_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 3.0), {
+ mud_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 3.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4510,7 +4510,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- nether_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
+ nether_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4518,7 +4518,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- andesite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ andesite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4526,7 +4526,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- red_nether_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
+ red_nether_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4534,7 +4534,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- sandstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8), {
+ sandstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.8, 0.8).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4542,7 +4542,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- end_stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 9.0), {
+ end_stone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 9.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4550,7 +4550,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
"west": WallWest::None,
},
- diorite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ diorite_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4593,16 +4593,16 @@ make_block_states! {
stonecutter => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
"facing": FacingCardinal::North,
},
- bell => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 5.0), {
+ bell => BlockBehavior::new().requires_correct_tool_for_drops().strength(5.0, 5.0).force_solid(true), {
"attachment": Attachment::Floor,
"facing": FacingCardinal::North,
"powered": Powered(false),
},
- lantern => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
+ lantern => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5).force_solid(true), {
"hanging": Hanging(false),
"waterlogged": Waterlogged(false),
},
- soul_lantern => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5), {
+ soul_lantern => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 3.5).force_solid(true), {
"hanging": Hanging(false),
"waterlogged": Waterlogged(false),
},
@@ -4672,10 +4672,10 @@ make_block_states! {
"type": Type::Bottom,
"waterlogged": Waterlogged(false),
},
- crimson_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ crimson_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
- warped_pressure_plate => BlockBehavior::new().strength(0.5, 0.5), {
+ warped_pressure_plate => BlockBehavior::new().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
crimson_fence => BlockBehavior::new().strength(2.0, 3.0), {
@@ -4706,13 +4706,13 @@ make_block_states! {
"powered": Powered(false),
"waterlogged": Waterlogged(false),
},
- crimson_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ crimson_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
"powered": Powered(false),
},
- warped_fence_gate => BlockBehavior::new().strength(2.0, 3.0), {
+ warped_fence_gate => BlockBehavior::new().strength(2.0, 3.0).force_solid(true), {
"facing": FacingCardinal::North,
"in_wall": InWall(false),
"open": Open(false),
@@ -4754,19 +4754,19 @@ make_block_states! {
"open": Open(false),
"powered": Powered(false),
},
- crimson_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ crimson_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": CrimsonSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- warped_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ warped_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"rotation": WarpedSignRotation::_0,
"waterlogged": Waterlogged(false),
},
- crimson_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ crimson_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
- warped_wall_sign => BlockBehavior::new().strength(1.0, 1.0), {
+ warped_wall_sign => BlockBehavior::new().strength(1.0, 1.0).force_solid(true), {
"facing": FacingCardinal::North,
"waterlogged": Waterlogged(false),
},
@@ -4810,7 +4810,7 @@ make_block_states! {
"shape": StairShape::Straight,
"waterlogged": Waterlogged(false),
},
- blackstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ blackstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4836,7 +4836,7 @@ make_block_states! {
"shape": StairShape::Straight,
"waterlogged": Waterlogged(false),
},
- polished_blackstone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ polished_blackstone_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -4855,7 +4855,7 @@ make_block_states! {
"type": Type::Bottom,
"waterlogged": Waterlogged(false),
},
- polished_blackstone_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5), {
+ polished_blackstone_pressure_plate => BlockBehavior::new().requires_correct_tool_for_drops().strength(0.5, 0.5).force_solid(true), {
"powered": Powered(false),
},
polished_blackstone_button => BlockBehavior::new().strength(0.5, 0.5), {
@@ -4863,7 +4863,7 @@ make_block_states! {
"facing": FacingCardinal::North,
"powered": Powered(false),
},
- polished_blackstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0), {
+ polished_blackstone_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(2.0, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -5012,7 +5012,7 @@ make_block_states! {
},
amethyst_block => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 1.5), {},
budding_amethyst => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 1.5), {},
- amethyst_cluster => BlockBehavior::new().strength(1.5, 1.5), {
+ amethyst_cluster => BlockBehavior::new().strength(1.5, 1.5).force_solid(true), {
"facing": FacingCubic::Up,
"waterlogged": Waterlogged(false),
},
@@ -5039,7 +5039,7 @@ make_block_states! {
"shape": StairShape::Straight,
"waterlogged": Waterlogged(false),
},
- tuff_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ tuff_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -5058,7 +5058,7 @@ make_block_states! {
"shape": StairShape::Straight,
"waterlogged": Waterlogged(false),
},
- polished_tuff_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ polished_tuff_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -5078,7 +5078,7 @@ make_block_states! {
"shape": StairShape::Straight,
"waterlogged": Waterlogged(false),
},
- tuff_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0), {
+ tuff_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(1.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -5102,7 +5102,7 @@ make_block_states! {
"waterlogged": Waterlogged(false),
},
sculk => BlockBehavior::new().strength(0.2, 0.2), {},
- sculk_vein => BlockBehavior::new().strength(0.2, 0.2), {
+ sculk_vein => BlockBehavior::new().strength(0.2, 0.2).force_solid(true), {
"down": Down(false),
"east": East(false),
"north": North(false),
@@ -5393,12 +5393,12 @@ make_block_states! {
"lit": Lit(false),
"powered": Powered(false),
},
- lightning_rod => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0), {
+ lightning_rod => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.0, 6.0).force_solid(true), {
"facing": FacingCubic::Up,
"powered": Powered(false),
"waterlogged": Waterlogged(false),
},
- pointed_dripstone => BlockBehavior::new().strength(1.5, 3.0), {
+ pointed_dripstone => BlockBehavior::new().strength(1.5, 3.0).force_solid(true), {
"thickness": Thickness::Tip,
"vertical_direction": VerticalDirection::Up,
"waterlogged": Waterlogged(false),
@@ -5412,15 +5412,15 @@ make_block_states! {
"berries": Berries(false),
},
spore_blossom => BlockBehavior::new(), {},
- azalea => BlockBehavior::new(), {},
- flowering_azalea => BlockBehavior::new(), {},
+ azalea => BlockBehavior::new().force_solid(false), {},
+ flowering_azalea => BlockBehavior::new().force_solid(false), {},
moss_carpet => BlockBehavior::new().strength(0.1, 0.1), {},
pink_petals => BlockBehavior::new(), {
"facing": FacingCardinal::North,
"flower_amount": PinkPetalsFlowerAmount::_1,
},
moss_block => BlockBehavior::new().strength(0.1, 0.1), {},
- big_dripleaf => BlockBehavior::new().strength(0.1, 0.1), {
+ big_dripleaf => BlockBehavior::new().strength(0.1, 0.1).force_solid(false), {
"facing": FacingCardinal::North,
"tilt": Tilt::None,
"waterlogged": Waterlogged(false),
@@ -5453,7 +5453,7 @@ make_block_states! {
"type": Type::Bottom,
"waterlogged": Waterlogged(false),
},
- cobbled_deepslate_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
+ cobbled_deepslate_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -5472,7 +5472,7 @@ make_block_states! {
"type": Type::Bottom,
"waterlogged": Waterlogged(false),
},
- polished_deepslate_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
+ polished_deepslate_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -5491,7 +5491,7 @@ make_block_states! {
"type": Type::Bottom,
"waterlogged": Waterlogged(false),
},
- deepslate_tile_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
+ deepslate_tile_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
@@ -5510,7 +5510,7 @@ make_block_states! {
"type": Type::Bottom,
"waterlogged": Waterlogged(false),
},
- deepslate_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0), {
+ deepslate_brick_wall => BlockBehavior::new().requires_correct_tool_for_drops().strength(3.5, 6.0).force_solid(true), {
"east": WallEast::None,
"north": WallNorth::None,
"south": WallSouth::None,
diff --git a/azalea-client/src/entity_query.rs b/azalea-client/src/entity_query.rs
index be892ee5..c711253a 100644
--- a/azalea-client/src/entity_query.rs
+++ b/azalea-client/src/entity_query.rs
@@ -106,9 +106,7 @@ where
fn find(&self, ecs_lock: Arc<Mutex<World>>) -> Option<Entity> {
let mut ecs = ecs_lock.lock();
let mut query = ecs.query_filtered::<(Entity, Q), Filter>();
- let entity = query.iter(&ecs).find(|(_, q)| (self)(q)).map(|(e, _)| e);
-
- entity
+ query.iter(&ecs).find(|(_, q)| (self)(q)).map(|(e, _)| e)
}
}
diff --git a/azalea-client/src/plugins/brand.rs b/azalea-client/src/plugins/brand.rs
index e15a6c67..5ee8e52c 100644
--- a/azalea-client/src/plugins/brand.rs
+++ b/azalea-client/src/plugins/brand.rs
@@ -24,7 +24,7 @@ impl Plugin for BrandPlugin {
}
}
-fn handle_end_login_state(
+pub fn handle_end_login_state(
mut removed: RemovedComponents<InLoginState>,
query: Query<&ClientInformation>,
mut send_packet_events: EventWriter<SendConfigPacketEvent>,
diff --git a/azalea-core/src/aabb.rs b/azalea-core/src/aabb.rs
index fe45c35e..6796e79c 100755
--- a/azalea-core/src/aabb.rs
+++ b/azalea-core/src/aabb.rs
@@ -26,26 +26,26 @@ pub struct ClipPointOpts<'a> {
}
impl AABB {
- pub fn contract(&self, x: f64, y: f64, z: f64) -> AABB {
+ pub fn contract(&self, amount: Vec3) -> AABB {
let mut min = self.min;
let mut max = self.max;
- if x < 0.0 {
- min.x -= x;
- } else if x > 0.0 {
- max.x -= x;
+ if amount.x < 0.0 {
+ min.x -= amount.x;
+ } else if amount.x > 0.0 {
+ max.x -= amount.x;
}
- if y < 0.0 {
- min.y -= y;
- } else if y > 0.0 {
- max.y -= y;
+ if amount.y < 0.0 {
+ min.y -= amount.y;
+ } else if amount.y > 0.0 {
+ max.y -= amount.y;
}
- if z < 0.0 {
- min.z -= z;
- } else if z > 0.0 {
- max.z -= z;
+ if amount.z < 0.0 {
+ min.z -= amount.z;
+ } else if amount.z > 0.0 {
+ max.z -= amount.z;
}
AABB { min, max }
@@ -84,20 +84,23 @@ impl AABB {
}
}
- pub fn inflate(&self, x: f64, y: f64, z: f64) -> AABB {
- let min_x = self.min.x - x;
- let min_y = self.min.y - y;
- let min_z = self.min.z - z;
+ pub fn inflate(&self, amount: Vec3) -> AABB {
+ let min_x = self.min.x - amount.x;
+ let min_y = self.min.y - amount.y;
+ let min_z = self.min.z - amount.z;
- let max_x = self.max.x + x;
- let max_y = self.max.y + y;
- let max_z = self.max.z + z;
+ let max_x = self.max.x + amount.x;
+ let max_y = self.max.y + amount.y;
+ let max_z = self.max.z + amount.z;
AABB {
min: Vec3::new(min_x, min_y, min_z),
max: Vec3::new(max_x, max_y, max_z),
}
}
+ pub fn inflate_all(&self, amount: f64) -> AABB {
+ self.inflate(Vec3::new(amount, amount, amount))
+ }
pub fn intersect(&self, other: &AABB) -> AABB {
let min_x = self.min.x.max(other.min.x);
@@ -144,17 +147,17 @@ impl AABB {
&& self.min.z < other.max.z
&& self.max.z > other.min.z
}
- pub fn intersects_vec3(&self, other: &Vec3, other2: &Vec3) -> bool {
+ pub fn intersects_vec3(&self, corner1: &Vec3, corner2: &Vec3) -> bool {
self.intersects_aabb(&AABB {
min: Vec3::new(
- other.x.min(other2.x),
- other.y.min(other2.y),
- other.z.min(other2.z),
+ corner1.x.min(corner2.x),
+ corner1.y.min(corner2.y),
+ corner1.z.min(corner2.z),
),
max: Vec3::new(
- other.x.max(other2.x),
- other.y.max(other2.y),
- other.z.max(other2.z),
+ corner1.x.max(corner2.x),
+ corner1.y.max(corner2.y),
+ corner1.z.max(corner2.z),
),
})
}
@@ -183,12 +186,11 @@ impl AABB {
)
}
- pub fn deflate(&mut self, x: f64, y: f64, z: f64) -> AABB {
- self.inflate(-x, -y, -z)
+ pub fn deflate(&self, amount: Vec3) -> AABB {
+ self.inflate(Vec3::new(-amount.x, -amount.y, -amount.z))
}
-
- pub fn deflate_all(&mut self, amount: f64) -> AABB {
- self.deflate(amount, amount, amount)
+ pub fn deflate_all(&self, amount: f64) -> AABB {
+ self.deflate(Vec3::new(amount, amount, amount))
}
pub fn clip(&self, min: &Vec3, max: &Vec3) -> Option<Vec3> {
@@ -434,11 +436,11 @@ impl AABB {
let new_center = center + vector;
for aabb in boxes {
- let inflated = aabb.inflate(
+ let inflated = aabb.inflate(Vec3::new(
self.get_size(Axis::X) * 0.5,
self.get_size(Axis::Y) * 0.5,
self.get_size(Axis::Z) * 0.5,
- );
+ ));
if inflated.contains(&new_center) || inflated.contains(&center) {
return true;
}
diff --git a/azalea-core/src/delta.rs b/azalea-core/src/delta.rs
index 238262a2..dd598f77 100755
--- a/azalea-core/src/delta.rs
+++ b/azalea-core/src/delta.rs
@@ -51,8 +51,8 @@ impl Vec3 {
pub fn normalize(&self) -> Vec3 {
let length = f64::sqrt(self.x * self.x + self.y * self.y + self.z * self.z);
- if length < 1e-4 {
- return Vec3::default();
+ if length < 1e-5 {
+ return Vec3::ZERO;
}
Vec3 {
x: self.x / length,
diff --git a/azalea-core/src/direction.rs b/azalea-core/src/direction.rs
index d458f487..656cab1b 100755
--- a/azalea-core/src/direction.rs
+++ b/azalea-core/src/direction.rs
@@ -17,9 +17,9 @@ pub enum Direction {
impl Direction {
pub const HORIZONTAL: [Direction; 4] = [
Direction::North,
+ Direction::East,
Direction::South,
Direction::West,
- Direction::East,
];
pub const VERTICAL: [Direction; 2] = [Direction::Down, Direction::Up];
diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs
index cba58415..5d923d39 100755
--- a/azalea-core/src/position.rs
+++ b/azalea-core/src/position.rs
@@ -309,6 +309,21 @@ impl Vec3 {
let z = self.z * (x_delta as f64) - self.x * (y_delta as f64);
Vec3 { x, y, z }
}
+
+ pub fn to_block_pos_floor(&self) -> BlockPos {
+ BlockPos {
+ x: self.x.floor() as i32,
+ y: self.y.floor() as i32,
+ z: self.z.floor() as i32,
+ }
+ }
+ pub fn to_block_pos_ceil(&self) -> BlockPos {
+ BlockPos {
+ x: self.x.ceil() as i32,
+ y: self.y.ceil() as i32,
+ z: self.z.ceil() as i32,
+ }
+ }
}
/// The coordinates of a block in the world. For entities (if the coordinate
@@ -600,6 +615,16 @@ impl From<ChunkSectionPos> for ChunkPos {
ChunkPos { x: pos.x, z: pos.z }
}
}
+impl From<&Vec3> for ChunkSectionPos {
+ fn from(pos: &Vec3) -> Self {
+ ChunkSectionPos::from(&BlockPos::from(pos))
+ }
+}
+impl From<Vec3> for ChunkSectionPos {
+ fn from(pos: Vec3) -> Self {
+ ChunkSectionPos::from(&pos)
+ }
+}
impl From<&BlockPos> for ChunkBlockPos {
#[inline]
diff --git a/azalea-entity/src/lib.rs b/azalea-entity/src/lib.rs
index 49e42017..4893878a 100644
--- a/azalea-entity/src/lib.rs
+++ b/azalea-entity/src/lib.rs
@@ -209,8 +209,8 @@ impl From<&LastSentPosition> for BlockPos {
///
/// If this is true, the entity will try to jump every tick. It's equivalent to
/// the space key being held in vanilla.
-#[derive(Debug, Component, Copy, Clone, Deref, DerefMut, Default)]
-pub struct Jumping(bool);
+#[derive(Debug, Component, Copy, Clone, Deref, DerefMut, Default, PartialEq, Eq)]
+pub struct Jumping(pub bool);
/// A component that contains the direction an entity is looking.
#[derive(Debug, Component, Copy, Clone, Default, PartialEq, AzBuf)]
diff --git a/azalea-physics/src/clip.rs b/azalea-physics/src/clip.rs
index ea5940a5..7c16f5d4 100644
--- a/azalea-physics/src/clip.rs
+++ b/azalea-physics/src/clip.rs
@@ -11,9 +11,7 @@ use azalea_core::{
math::{self, EPSILON, lerp},
position::{BlockPos, Vec3},
};
-use azalea_inventory::ItemStack;
use azalea_world::ChunkStorage;
-use bevy_ecs::entity::Entity;
use crate::collision::{BlockWithShape, EMPTY_SHAPE, VoxelShape};
@@ -92,15 +90,6 @@ impl FluidPickType {
}
}
-#[derive(Debug, Clone)]
-pub struct EntityCollisionContext {
- pub descending: bool,
- pub entity_bottom: f64,
- pub held_item: ItemStack,
- // pub can_stand_on_fluid: Box<dyn Fn(&FluidState) -> bool>,
- pub entity: Entity,
-}
-
pub fn clip(chunk_storage: &ChunkStorage, context: ClipContext) -> BlockHitResult {
traverse_blocks(
context.from,
diff --git a/azalea-physics/src/collision/entity_collisions.rs b/azalea-physics/src/collision/entity_collisions.rs
new file mode 100644
index 00000000..1300cf34
--- /dev/null
+++ b/azalea-physics/src/collision/entity_collisions.rs
@@ -0,0 +1,97 @@
+use azalea_core::aabb::AABB;
+use azalea_entity::{
+ LocalEntity, Physics,
+ metadata::{AbstractBoat, Shulker},
+};
+use azalea_world::Instance;
+use bevy_ecs::{
+ entity::Entity,
+ query::{Or, With, Without},
+ system::Query,
+};
+use tracing::error;
+
+use super::VoxelShape;
+
+/// This query matches on entities that we can collide with. That is, boats and
+/// shulkers.
+///
+/// If you want to use this in a more complex query, use
+/// [`CollidableEntityFilter`] as a filter instead.
+pub type CollidableEntityQuery<'world, 'state> = Query<'world, 'state, (), CollidableEntityFilter>;
+/// This filter matches on entities that we can collide with (boats and
+/// shulkers).
+///
+/// Use [`CollidableEntityQuery`] if you want an empty query that matches with
+/// this.
+pub type CollidableEntityFilter = Or<(With<AbstractBoat>, With<Shulker>)>;
+
+pub type PhysicsQuery<'world, 'state, 'a> =
+ Query<'world, 'state, &'a Physics, Without<LocalEntity>>;
+
+pub fn get_entity_collisions(
+ world: &Instance,
+ aabb: &AABB,
+ source_entity: Option<Entity>,
+ physics_query: &PhysicsQuery,
+ collidable_entity_query: &CollidableEntityQuery,
+) -> Vec<VoxelShape> {
+ if aabb.size() < 1.0E-7 {
+ return vec![];
+ }
+
+ let collision_predicate = |entity| collidable_entity_query.get(entity).is_ok();
+
+ let collidable_entities = get_entities(
+ world,
+ source_entity,
+ &aabb.inflate_all(1.0E-7),
+ &collision_predicate,
+ physics_query,
+ );
+
+ collidable_entities
+ .into_iter()
+ .map(|(_entity, aabb)| VoxelShape::from(aabb))
+ .collect()
+}
+
+/// Return all entities that are colliding with the given bounding box and match
+/// the given predicate.
+///
+/// `source_entity` is the entity that the bounding box belongs to, and won't be
+/// one of the returned entities.
+pub fn get_entities(
+ world: &Instance,
+ source_entity: Option<Entity>,
+ aabb: &AABB,
+ predicate: &dyn Fn(Entity) -> bool,
+ physics_query: &PhysicsQuery,
+) -> Vec<(Entity, AABB)> {
+ let mut matches = Vec::new();
+
+ super::world_collisions::for_entities_in_chunks_colliding_with(
+ world,
+ aabb,
+ |_chunk_pos, entities_in_chunk| {
+ // now check if the entity itself collides
+ for &candidate in entities_in_chunk {
+ if Some(candidate) != source_entity && predicate(candidate) {
+ let Ok(physics) = physics_query.get(candidate) else {
+ error!(
+ "Entity {candidate} (found from for_entities_in_chunks_colliding_with) is missing required components."
+ );
+ continue;
+ };
+
+ let candidate_aabb = physics.bounding_box;
+ if aabb.intersects_aabb(&candidate_aabb) {
+ matches.push((candidate, physics.bounding_box));
+ }
+ }
+ }
+ },
+ );
+
+ matches
+}
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index 540cf7d4..77af1232 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -1,8 +1,9 @@
mod blocks;
mod discrete_voxel_shape;
+pub mod entity_collisions;
mod mergers;
mod shape;
-mod world_collisions;
+pub mod world_collisions;
use std::{ops::Add, sync::LazyLock};
@@ -279,7 +280,7 @@ fn collide_bounding_box(
// TODO: world border
let block_collisions =
- get_block_collisions(world, entity_bounding_box.expand_towards(movement));
+ get_block_collisions(world, &entity_bounding_box.expand_towards(movement));
collision_boxes.extend(block_collisions);
collide_with_shapes(movement, *entity_bounding_box, &collision_boxes)
}
@@ -392,6 +393,11 @@ fn calculate_shape_for_fluid(amount: u8) -> VoxelShape {
///
/// This is marked as deprecated in Minecraft.
pub fn legacy_blocks_motion(block: BlockState) -> bool {
+ if block == BlockState::AIR {
+ // fast path
+ return false;
+ }
+
let registry_block = azalea_registry::Block::from(block);
legacy_calculate_solid(block)
&& registry_block != azalea_registry::Block::Cobweb
diff --git a/azalea-physics/src/collision/shape.rs b/azalea-physics/src/collision/shape.rs
index 726e62ad..fc5615c3 100755
--- a/azalea-physics/src/collision/shape.rs
+++ b/azalea-physics/src/collision/shape.rs
@@ -194,7 +194,7 @@ impl Shapes {
}
/// Check if the op is true anywhere when joining the two shapes
- /// vanilla calls this joinIsNotEmpty
+ /// vanilla calls this joinIsNotEmpty (join_is_not_empty).
pub fn matches_anywhere(
a: &VoxelShape,
b: &VoxelShape,
@@ -574,13 +574,18 @@ impl VoxelShape {
}
}
-impl From<AABB> for VoxelShape {
- fn from(aabb: AABB) -> Self {
+impl From<&AABB> for VoxelShape {
+ fn from(aabb: &AABB) -> Self {
box_shape(
aabb.min.x, aabb.min.y, aabb.min.z, aabb.max.x, aabb.max.y, aabb.max.z,
)
}
}
+impl From<AABB> for VoxelShape {
+ fn from(aabb: AABB) -> Self {
+ VoxelShape::from(&aabb)
+ }
+}
#[derive(Clone, PartialEq, Debug)]
pub struct ArrayVoxelShape {
diff --git a/azalea-physics/src/collision/world_collisions.rs b/azalea-physics/src/collision/world_collisions.rs
index 3aede743..ded31275 100644
--- a/azalea-physics/src/collision/world_collisions.rs
+++ b/azalea-physics/src/collision/world_collisions.rs
@@ -1,19 +1,21 @@
-use std::sync::Arc;
+use std::{collections::HashSet, sync::Arc};
-use azalea_block::BlockState;
+use azalea_block::{BlockState, fluid_state::FluidState};
use azalea_core::{
- cursor3d::{Cursor3d, CursorIterationType},
+ cursor3d::{Cursor3d, CursorIteration, CursorIterationType},
math::EPSILON,
- position::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos},
+ position::{BlockPos, ChunkBlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos, Vec3},
};
+use azalea_inventory::ItemStack;
use azalea_world::{Chunk, Instance};
+use bevy_ecs::entity::Entity;
use parking_lot::RwLock;
use super::{BLOCK_SHAPE, Shapes};
use crate::collision::{AABB, BlockWithShape, VoxelShape};
-pub fn get_block_collisions(world: &Instance, aabb: AABB) -> Vec<VoxelShape> {
- let mut state = BlockCollisionsState::new(world, aabb);
+pub fn get_block_collisions(world: &Instance, aabb: &AABB) -> Vec<VoxelShape> {
+ let mut state = BlockCollisionsState::new(world, aabb, EntityCollisionContext::of(None));
let mut block_collisions = Vec::new();
let initial_chunk_pos = ChunkPos::from(state.cursor.origin());
@@ -21,25 +23,80 @@ pub fn get_block_collisions(world: &Instance, aabb: AABB) -> Vec<VoxelShape> {
let initial_chunk = initial_chunk.as_deref().map(RwLock::read);
while let Some(item) = state.cursor.next() {
+ state.compute_next(
+ item,
+ &mut block_collisions,
+ initial_chunk_pos,
+ initial_chunk.as_deref(),
+ );
+ }
+
+ block_collisions
+}
+
+pub fn get_block_and_liquid_collisions(world: &Instance, aabb: &AABB) -> Vec<VoxelShape> {
+ let mut state = BlockCollisionsState::new(
+ world,
+ aabb,
+ EntityCollisionContext::of(None).with_include_liquids(true),
+ );
+ let mut block_collisions = Vec::new();
+
+ let initial_chunk_pos = ChunkPos::from(state.cursor.origin());
+ let initial_chunk = world.chunks.get(&initial_chunk_pos);
+ let initial_chunk = initial_chunk.as_deref().map(RwLock::read);
+
+ while let Some(item) = state.cursor.next() {
+ state.compute_next(
+ item,
+ &mut block_collisions,
+ initial_chunk_pos,
+ initial_chunk.as_deref(),
+ );
+ }
+
+ block_collisions
+}
+
+pub struct BlockCollisionsState<'a> {
+ pub world: &'a Instance,
+ pub aabb: &'a AABB,
+ pub entity_shape: VoxelShape,
+ pub cursor: Cursor3d,
+
+ _context: EntityCollisionContext,
+
+ cached_sections: Vec<(ChunkSectionPos, azalea_world::Section)>,
+ cached_block_shapes: Vec<(BlockState, &'static VoxelShape)>,
+}
+
+impl<'a> BlockCollisionsState<'a> {
+ fn compute_next(
+ &mut self,
+ item: CursorIteration,
+ block_collisions: &mut Vec<VoxelShape>,
+ initial_chunk_pos: ChunkPos,
+ initial_chunk: Option<&Chunk>,
+ ) {
if item.iteration_type == CursorIterationType::Corner {
- continue;
+ return;
}
let item_chunk_pos = ChunkPos::from(item.pos);
let block_state: BlockState = if item_chunk_pos == initial_chunk_pos {
match &initial_chunk {
Some(initial_chunk) => initial_chunk
- .get(&ChunkBlockPos::from(item.pos), state.world.chunks.min_y)
+ .get(&ChunkBlockPos::from(item.pos), self.world.chunks.min_y)
.unwrap_or(BlockState::AIR),
_ => BlockState::AIR,
}
} else {
- state.get_block_state(item.pos)
+ self.get_block_state(item.pos)
};
if block_state.is_air() {
// fast path since we can't collide with air
- continue;
+ return;
}
// TODO: continue if self.only_suffocating_blocks and the block is not
@@ -47,43 +104,29 @@ pub fn get_block_collisions(world: &Instance, aabb: AABB) -> Vec<VoxelShape> {
// if it's a full block do a faster collision check
if block_state.is_collision_shape_full() {
- if !state.aabb.intersects_aabb(&AABB {
+ if !self.aabb.intersects_aabb(&AABB {
min: item.pos.to_vec3_floored(),
max: (item.pos + 1).to_vec3_floored(),
}) {
- continue;
+ return;
}
block_collisions.push(BLOCK_SHAPE.move_relative(item.pos.to_vec3_floored()));
- continue;
+ return;
}
- let block_shape = state.get_block_shape(block_state);
+ let block_shape = self.get_block_shape(block_state);
let block_shape = block_shape.move_relative(item.pos.to_vec3_floored());
// if the entity shape and block shape don't collide, continue
- if !Shapes::matches_anywhere(&block_shape, &state.entity_shape, |a, b| a && b) {
- continue;
+ if !Shapes::matches_anywhere(&block_shape, &self.entity_shape, |a, b| a && b) {
+ return;
}
block_collisions.push(block_shape);
}
- block_collisions
-}
-
-pub struct BlockCollisionsState<'a> {
- pub world: &'a Instance,
- pub aabb: AABB,
- pub entity_shape: VoxelShape,
- pub cursor: Cursor3d,
-
- cached_sections: Vec<(ChunkSectionPos, azalea_world::Section)>,
- cached_block_shapes: Vec<(BlockState, &'static VoxelShape)>,
-}
-
-impl<'a> BlockCollisionsState<'a> {
- pub fn new(world: &'a Instance, aabb: AABB) -> Self {
+ pub fn new(world: &'a Instance, aabb: &'a AABB, context: EntityCollisionContext) -> Self {
let origin = BlockPos {
x: (aabb.min.x - EPSILON).floor() as i32 - 1,
y: (aabb.min.y - EPSILON).floor() as i32 - 1,
@@ -104,6 +147,8 @@ impl<'a> BlockCollisionsState<'a> {
entity_shape: VoxelShape::from(aabb),
cursor,
+ _context: context,
+
cached_sections: Vec::new(),
cached_block_shapes: Vec::new(),
}
@@ -182,3 +227,78 @@ impl<'a> BlockCollisionsState<'a> {
shape
}
}
+
+pub struct EntityCollisionContext {
+ pub descending: bool,
+ pub entity_bottom: f64,
+ pub held_item: ItemStack,
+ can_stand_on_fluid_predicate: CanStandOnFluidPredicate,
+ pub entity: Option<Entity>,
+}
+
+impl EntityCollisionContext {
+ pub fn of(entity: Option<Entity>) -> Self {
+ Self {
+ descending: false,
+ entity_bottom: 0.0,
+ held_item: ItemStack::Empty,
+ can_stand_on_fluid_predicate: CanStandOnFluidPredicate::PassToEntity,
+ entity,
+ }
+ }
+ pub fn with_include_liquids(mut self, include_liquids: bool) -> Self {
+ self.can_stand_on_fluid_predicate = if include_liquids {
+ CanStandOnFluidPredicate::AlwaysTrue
+ } else {
+ CanStandOnFluidPredicate::PassToEntity
+ };
+ self
+ }
+
+ pub fn can_stand_on_fluid(&self, above: &FluidState, target: &FluidState) -> bool {
+ self.can_stand_on_fluid_predicate.matches(target) && !above.is_same_kind(target)
+ }
+}
+
+enum CanStandOnFluidPredicate {
+ PassToEntity,
+ AlwaysTrue,
+}
+impl CanStandOnFluidPredicate {
+ pub fn matches(&self, _state: &FluidState) -> bool {
+ match self {
+ Self::AlwaysTrue => true,
+ // minecraft sometimes returns true for striders here, false for every other entity
+ // though
+ Self::PassToEntity => false,
+ }
+ }
+}
+
+/// This basically gets all the chunks that an entity colliding with
+/// that bounding box could be in.
+///
+/// This is forEachAccessibleNonEmptySection in vanilla Minecraft because they
+/// sort entities into sections instead of just chunks. In theory this might be
+/// a performance loss for Azalea. If this ever turns out to be a bottleneck,
+/// then maybe you should try having it do that instead.
+pub fn for_entities_in_chunks_colliding_with(
+ world: &Instance,
+ aabb: &AABB,
+ mut consumer: impl FnMut(ChunkPos, &HashSet<Entity>),
+) {
+ let min_section = ChunkSectionPos::from(aabb.min - Vec3::new(2., 4., 2.));
+ let max_section = ChunkSectionPos::from(aabb.max + Vec3::new(2., 0., 2.));
+
+ let min_chunk = ChunkPos::from(min_section);
+ let max_chunk = ChunkPos::from(max_section);
+
+ for chunk_x in min_chunk.x..=max_chunk.x {
+ for chunk_z in min_chunk.z..=max_chunk.z {
+ let chunk_pos = ChunkPos::new(chunk_x, chunk_z);
+ if let Some(entities) = world.entities_by_chunk.get(&chunk_pos) {
+ consumer(chunk_pos, entities);
+ }
+ }
+ }
+}
diff --git a/azalea-physics/src/fluids.rs b/azalea-physics/src/fluids.rs
index bbc044f6..f8643b9c 100644
--- a/azalea-physics/src/fluids.rs
+++ b/azalea-physics/src/fluids.rs
@@ -27,6 +27,8 @@ pub fn update_in_water_state_and_do_fluid_pushing(
.expect("All entities with InLoadedChunk should be in a valid world");
let world = world_lock.read();
+ // reset the heights since they're going to be set in
+ // update_in_water_state_and_do_water_current_pushing
physics.water_fluid_height = 0.;
physics.lava_fluid_height = 0.;
@@ -110,9 +112,9 @@ fn update_fluid_height_and_do_fluid_pushing(
let mut additional_player_delta = Vec3::default();
let mut num_fluids_being_touched = 0;
- for cur_x in min_x..=max_x {
- for cur_y in min_y..=max_y {
- for cur_z in min_z..=max_z {
+ for cur_x in min_x..max_x {
+ for cur_y in min_y..max_y {
+ for cur_z in min_z..max_z {
let cur_pos = BlockPos::new(cur_x, cur_y, cur_z);
let Some(fluid_at_cur_pos) = world.get_fluid_state(&cur_pos) else {
continue;
@@ -184,42 +186,44 @@ pub fn get_fluid_flow(fluid: &FluidState, world: &Instance, pos: BlockPos) -> Ve
let mut z_flow: f64 = 0.;
let mut x_flow: f64 = 0.;
+ let cur_fluid_height = fluid.height();
+
for direction in Direction::HORIZONTAL {
let adjacent_block_pos = pos.offset_with_direction(direction);
- let adjacent_fluid_state = world
- .get_fluid_state(&adjacent_block_pos)
+
+ let adjacent_block_state = world
+ .get_block_state(&adjacent_block_pos)
.unwrap_or_default();
- if fluid.affects_flow(&adjacent_fluid_state) {
- let mut adjacent_fluid_height = adjacent_fluid_state.height();
- let mut adjacent_height_difference: f32 = 0.;
-
- if adjacent_fluid_height == 0. {
- if !legacy_blocks_motion(
- world
- .get_block_state(&adjacent_block_pos)
- .unwrap_or_default(),
- ) {
- let block_pos_below_adjacent = adjacent_block_pos.down(1);
- let fluid_below_adjacent = world
- .get_fluid_state(&block_pos_below_adjacent)
- .unwrap_or_default();
-
- if fluid.affects_flow(&fluid_below_adjacent) {
- adjacent_fluid_height = fluid_below_adjacent.height();
- if adjacent_fluid_height > 0. {
- adjacent_height_difference =
- fluid.height() - (adjacent_fluid_height - 0.8888889);
- }
+ let adjacent_fluid_state = FluidState::from(adjacent_block_state);
+
+ if !fluid.affects_flow(&adjacent_fluid_state) {
+ continue;
+ };
+ let mut adjacent_fluid_height = adjacent_fluid_state.height();
+ let mut adjacent_height_difference: f32 = 0.;
+
+ if adjacent_fluid_height == 0. {
+ if !legacy_blocks_motion(adjacent_block_state) {
+ let block_pos_below_adjacent = adjacent_block_pos.down(1);
+ let fluid_below_adjacent = world
+ .get_fluid_state(&block_pos_below_adjacent)
+ .unwrap_or_default();
+
+ if fluid.affects_flow(&fluid_below_adjacent) {
+ adjacent_fluid_height = fluid_below_adjacent.height();
+ if adjacent_fluid_height > 0. {
+ adjacent_height_difference =
+ cur_fluid_height - (adjacent_fluid_height - 0.8888889);
}
}
- } else if adjacent_fluid_height > 0. {
- adjacent_height_difference = fluid.height() - adjacent_fluid_height;
}
+ } else if adjacent_fluid_height > 0. {
+ adjacent_height_difference = cur_fluid_height - adjacent_fluid_height;
+ }
- if adjacent_height_difference != 0. {
- x_flow += (direction.x() as f32 * adjacent_height_difference) as f64;
- z_flow += (direction.z() as f32 * adjacent_height_difference) as f64;
- }
+ if adjacent_height_difference != 0. {
+ x_flow += (direction.x() as f32 * adjacent_height_difference) as f64;
+ z_flow += (direction.z() as f32 * adjacent_height_difference) as f64;
}
}
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs
index 0541042c..2e8132c8 100644
--- a/azalea-physics/src/lib.rs
+++ b/azalea-physics/src/lib.rs
@@ -90,44 +90,40 @@ pub fn ai_step(
physics.velocity.z = 0.;
}
- if let Some(jumping) = jumping {
- if **jumping {
- // TODO: jumping in liquids and jump delay
-
- let fluid_height = if physics.is_in_lava() {
- physics.lava_fluid_height
- } else if physics.is_in_water() {
- physics.water_fluid_height
- } else {
- 0.
- };
-
- let in_water = physics.is_in_water() && fluid_height > 0.;
- let fluid_jump_threshold = travel::fluid_jump_threshold();
-
- if !in_water || physics.on_ground() && fluid_height <= fluid_jump_threshold {
- if !physics.is_in_lava()
- || physics.on_ground() && fluid_height <= fluid_jump_threshold
+ if jumping == Some(&Jumping(true)) {
+ let fluid_height = if physics.is_in_lava() {
+ physics.lava_fluid_height
+ } else if physics.is_in_water() {
+ physics.water_fluid_height
+ } else {
+ 0.
+ };
+
+ let in_water = physics.is_in_water() && fluid_height > 0.;
+ let fluid_jump_threshold = travel::fluid_jump_threshold();
+
+ if !in_water || physics.on_ground() && fluid_height <= fluid_jump_threshold {
+ if !physics.is_in_lava()
+ || physics.on_ground() && fluid_height <= fluid_jump_threshold
+ {
+ if (physics.on_ground() || in_water && fluid_height <= fluid_jump_threshold)
+ && physics.no_jump_delay == 0
{
- if (physics.on_ground() || in_water && fluid_height <= fluid_jump_threshold)
- && physics.no_jump_delay == 0
- {
- jump_from_ground(
- &mut physics,
- position,
- look_direction,
- sprinting,
- instance_name,
- &instance_container,
- );
- physics.no_jump_delay = 10;
- }
- } else {
- jump_in_liquid(&mut physics);
+ jump_from_ground(
+ &mut physics,
+ position,
+ look_direction,
+ sprinting,
+ instance_name,
+ &instance_container,
+ );
+ physics.no_jump_delay = 10;
}
} else {
jump_in_liquid(&mut physics);
}
+ } else {
+ jump_in_liquid(&mut physics);
}
} else {
physics.no_jump_delay = 0;
@@ -417,7 +413,6 @@ fn handle_relative_friction_and_calculate_movement(
.unwrap_or_default()
.into();
- // TODO: powdered snow
if **on_climbable || block_at_feet == azalea_registry::Block::PowderSnow {
physics.velocity.y = 0.2;
}
diff --git a/azalea-physics/src/travel.rs b/azalea-physics/src/travel.rs
index e6145c18..0ee39f73 100644
--- a/azalea-physics/src/travel.rs
+++ b/azalea-physics/src/travel.rs
@@ -1,5 +1,8 @@
-use azalea_block::{Block, BlockState};
-use azalea_core::{aabb::AABB, position::Vec3};
+use azalea_block::{Block, BlockState, fluid_state::FluidState};
+use azalea_core::{
+ aabb::AABB,
+ position::{BlockPos, Vec3},
+};
use azalea_entity::{
Attributes, InLoadedChunk, Jumping, LocalEntity, LookDirection, OnClimbable, Physics, Pose,
Position, metadata::Sprinting, move_relative,
@@ -9,7 +12,11 @@ use bevy_ecs::prelude::*;
use crate::{
HandleRelativeFrictionAndCalculateMovementOpts,
- collision::{MoverType, move_colliding},
+ collision::{
+ MoverType, Shapes,
+ entity_collisions::{CollidableEntityQuery, PhysicsQuery, get_entity_collisions},
+ move_colliding,
+ },
get_block_pos_below_that_affects_movement, handle_relative_friction_and_calculate_movement,
};
@@ -19,6 +26,7 @@ use crate::{
pub fn travel(
mut query: Query<
(
+ Entity,
&mut Physics,
&mut LookDirection,
&mut Position,
@@ -32,8 +40,11 @@ pub fn travel(
(With<LocalEntity>, With<InLoadedChunk>),
>,
instance_container: Res<InstanceContainer>,
+ physics_query: PhysicsQuery,
+ collidable_entity_query: CollidableEntityQuery,
) {
for (
+ entity,
mut physics,
direction,
position,
@@ -59,13 +70,16 @@ pub fn travel(
// !this.canStandOnFluid(fluidAtBlock)` here but it doesn't matter
// for players
travel_in_fluid(
+ &world,
+ entity,
&mut physics,
&direction,
position,
attributes,
sprinting,
on_climbable,
- &world,
+ &physics_query,
+ &collidable_entity_query,
);
} else {
travel_in_air(
@@ -149,14 +163,18 @@ fn travel_in_air(
}
}
+#[allow(clippy::too_many_arguments)]
fn travel_in_fluid(
+ world: &Instance,
+ entity: Entity,
physics: &mut Physics,
direction: &LookDirection,
mut position: Mut<Position>,
attributes: &Attributes,
sprinting: Sprinting,
on_climbable: &OnClimbable,
- world: &Instance,
+ physics_query: &PhysicsQuery,
+ collidable_entity_query: &CollidableEntityQuery,
) {
let moving_down = physics.velocity.y <= 0.;
let y = position.y;
@@ -239,11 +257,13 @@ fn travel_in_fluid(
let velocity = physics.velocity;
if physics.horizontal_collision
&& is_free(
- physics.bounding_box,
world,
- velocity.x,
- velocity.y + 0.6 - position.y + y,
- velocity.z,
+ entity,
+ physics_query,
+ collidable_entity_query,
+ physics,
+ physics.bounding_box,
+ velocity.up(0.6).down(position.y).up(y),
)
{
physics.velocity.y = 0.3;
@@ -276,14 +296,97 @@ fn get_fluid_falling_adjusted_movement(
}
}
-fn is_free(bounding_box: AABB, world: &Instance, x: f64, y: f64, z: f64) -> bool {
- // let bounding_box = bounding_box.move_relative(Vec3::new(x, y, z));
+fn is_free(
+ world: &Instance,
+ source_entity: Entity,
+ physics_query: &PhysicsQuery,
+ collidable_entity_query: &CollidableEntityQuery,
+ entity_physics: &mut Physics,
+ bounding_box: AABB,
+ delta: Vec3,
+) -> bool {
+ let bounding_box = bounding_box.move_relative(delta);
+
+ no_collision(
+ world,
+ Some(source_entity),
+ physics_query,
+ collidable_entity_query,
+ entity_physics,
+ &bounding_box,
+ false,
+ ) && !contains_any_liquid(world, bounding_box)
+}
- let _ = (bounding_box, world, x, y, z);
+fn no_collision(
+ world: &Instance,
+ source_entity: Option<Entity>,
+ physics_query: &PhysicsQuery,
+ collidable_entity_query: &CollidableEntityQuery,
+ entity_physics: &mut Physics,
+ aabb: &AABB,
+ include_liquid_collisions: bool,
+) -> bool {
+ let collisions = if include_liquid_collisions {
+ crate::collision::world_collisions::get_block_and_liquid_collisions(world, aabb)
+ } else {
+ crate::collision::world_collisions::get_block_collisions(world, aabb)
+ };
- // TODO: implement this, see Entity.isFree
+ for collision in collisions {
+ if !collision.is_empty() {
+ return false;
+ }
+ }
+
+ if !get_entity_collisions(
+ world,
+ aabb,
+ source_entity,
+ physics_query,
+ collidable_entity_query,
+ )
+ .is_empty()
+ {
+ false
+ } else if source_entity.is_none() {
+ true
+ } else {
+ let collision = border_collision(entity_physics, aabb);
+ if let Some(collision) = collision {
+ // !Shapes.joinIsNotEmpty(collision, Shapes.create(aabb), BooleanOp.AND);
+ !Shapes::matches_anywhere(&collision.into(), &aabb.into(), |a, b| a && b)
+ } else {
+ true
+ }
+ }
+}
+
+fn border_collision(_entity_physics: &Physics, _aabb: &AABB) -> Option<AABB> {
+ // TODO: implement world border, see CollisionGetter.borderCollision
+
+ None
+}
+
+fn contains_any_liquid(world: &Instance, bounding_box: AABB) -> bool {
+ let min = bounding_box.min.to_block_pos_floor();
+ let max = bounding_box.max.to_block_pos_ceil();
+
+ for x in min.x..max.x {
+ for y in min.y..max.y {
+ for z in min.z..max.z {
+ let block_state = world
+ .chunks
+ .get_block_state(&BlockPos::new(x, y, z))
+ .unwrap_or_default();
+ if !FluidState::from(block_state).is_empty() {
+ return true;
+ }
+ }
+ }
+ }
- true
+ false
}
fn get_effective_gravity() -> f64 {
diff --git a/azalea-physics/tests/physics.rs b/azalea-physics/tests/physics.rs
index c9fcdf97..396c34f9 100644
--- a/azalea-physics/tests/physics.rs
+++ b/azalea-physics/tests/physics.rs
@@ -1,5 +1,9 @@
use std::sync::Arc;
+use azalea_block::{
+ BlockState, block_state::BlockStateIntegerRepr, fluid_state::to_or_from_legacy_fluid_level,
+ properties::WaterLevel,
+};
use azalea_core::{
position::{BlockPos, ChunkPos, Vec3},
registry_holder::RegistryHolder,
@@ -409,3 +413,137 @@ fn spawn_and_unload_world() {
app.world_mut().run_schedule(GameTick);
app.update();
}
+
+#[test]
+fn test_afk_pool() {
+ let mut app = make_test_app();
+ let world_lock = insert_overworld(&mut app);
+ let mut partial_world = PartialInstance::default();
+
+ partial_world.chunks.set(
+ &ChunkPos { x: 0, z: 0 },
+ Some(Chunk::default()),
+ &mut world_lock.write().chunks,
+ );
+ let setblock = |x: i32, y: i32, z: i32, b: BlockState| {
+ world_lock
+ .write()
+ .chunks
+ .set_block_state(&BlockPos { x, y, z }, b);
+ };
+
+ let stone = azalea_block::blocks::Stone {}.into();
+ let sign = azalea_block::blocks::OakSign {
+ rotation: azalea_block::properties::OakSignRotation::_0,
+ waterlogged: false,
+ }
+ .into();
+ let water = |level: u8| {
+ BlockState::from(azalea_block::blocks::Water {
+ level: WaterLevel::from(to_or_from_legacy_fluid_level(level) as BlockStateIntegerRepr),
+ })
+ };
+
+ let mut y = 69;
+
+ // first layer
+ {
+ setblock(1, y, 1, stone);
+ setblock(2, y, 1, stone);
+ setblock(3, y, 1, stone);
+ setblock(3, y, 2, stone);
+ setblock(3, y, 3, stone);
+ setblock(2, y, 3, stone);
+ setblock(1, y, 3, stone);
+ setblock(1, y, 2, stone);
+ }
+ // second layer
+ y += 1;
+ {
+ setblock(1, y, 0, stone);
+ setblock(2, y, 0, stone);
+ setblock(3, y, 0, stone);
+
+ setblock(0, y, 1, stone);
+ setblock(0, y, 2, stone);
+ setblock(0, y, 3, stone);
+
+ setblock(1, y, 4, stone);
+ setblock(2, y, 4, stone);
+ setblock(3, y, 4, stone);
+
+ setblock(4, y, 1, stone);
+ setblock(4, y, 2, stone);
+ setblock(4, y, 3, stone);
+
+ // middle block
+ setblock(2, y, 2, stone);
+
+ // sign
+ setblock(1, y, 1, sign);
+
+ // water
+ setblock(1, y, 2, water(8));
+ setblock(1, y, 3, water(7));
+ setblock(2, y, 3, water(6));
+ setblock(3, y, 3, water(5));
+ setblock(3, y, 2, water(4));
+ setblock(3, y, 1, water(3));
+ setblock(2, y, 1, water(2));
+ }
+ // third layer
+ y += 1;
+ {
+ setblock(1, y, 1, water(8));
+ setblock(2, y, 1, sign);
+ }
+
+ let entity = app
+ .world_mut()
+ .spawn((
+ EntityBundle::new(
+ Uuid::nil(),
+ Vec3 {
+ x: 3.5,
+ y: 70.,
+ z: 1.5,
+ },
+ azalea_registry::EntityKind::Player,
+ ResourceLocation::new("minecraft:overworld"),
+ ),
+ MinecraftEntityId(0),
+ LocalEntity,
+ ))
+ .id();
+
+ let mut blocks_visited = Vec::new();
+ let mut loops_done = 0;
+
+ for _ in 0..300 {
+ app.world_mut().run_schedule(GameTick);
+ app.update();
+
+ let entity_pos = app.world_mut().get::<Position>(entity).unwrap();
+ let entity_block_pos = BlockPos::from(entity_pos);
+
+ if !blocks_visited.contains(&entity_block_pos) {
+ blocks_visited.push(entity_block_pos);
+
+ if blocks_visited.len() == 8 {
+ loops_done += 1;
+ blocks_visited.clear();
+ }
+ }
+ }
+
+ assert_eq!(
+ blocks_visited.into_iter().collect::<Vec<_>>(),
+ vec![
+ BlockPos::new(3, 70, 2),
+ BlockPos::new(3, 70, 1),
+ BlockPos::new(2, 70, 1),
+ BlockPos::new(1, 70, 1),
+ ]
+ );
+ assert_eq!(loops_done, 1);
+}
diff --git a/azalea-protocol/src/connect.rs b/azalea-protocol/src/connect.rs
index a4c558a1..13a86ed8 100755
--- a/azalea-protocol/src/connect.rs
+++ b/azalea-protocol/src/connect.rs
@@ -296,7 +296,7 @@ impl Connection<ClientboundHandshakePacket, ServerboundHandshakePacket> {
let _ = socks5_impl::client::connect(&mut stream, address, proxy.auth)
.await
- .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+ .map_err(io::Error::other)?;
Self::new_from_stream(stream.into_inner()).await
}
diff --git a/azalea/src/accept_resource_packs.rs b/azalea/src/accept_resource_packs.rs
index 807ad355..560140d0 100644
--- a/azalea/src/accept_resource_packs.rs
+++ b/azalea/src/accept_resource_packs.rs
@@ -1,7 +1,7 @@
use azalea_client::InConfigState;
use azalea_client::chunks::handle_chunk_batch_finished_event;
use azalea_client::inventory::InventorySet;
-use azalea_client::packet::config::SendConfigPacketEvent;
+use azalea_client::packet::config::{SendConfigPacketEvent, handle_send_packet_event};
use azalea_client::packet::game::SendPacketEvent;
use azalea_client::packet::{death_event_on_0_health, game::ResourcePackEvent};
use azalea_client::respawn::perform_respawn;
@@ -23,7 +23,9 @@ impl Plugin for AcceptResourcePacksPlugin {
.before(perform_respawn)
.after(death_event_on_0_health)
.after(handle_chunk_batch_finished_event)
- .after(InventorySet),
+ .after(InventorySet)
+ .before(handle_send_packet_event)
+ .after(azalea_client::brand::handle_end_login_state),
);
}
}
diff --git a/codegen/genblocks.py b/codegen/genblocks.py
index 1024072a..d0bea909 100755
--- a/codegen/genblocks.py
+++ b/codegen/genblocks.py
@@ -13,13 +13,14 @@ def generate(version_id):
'1.20.3-pre4', 'shapes')
pixlyzer_block_datas = lib.extract.get_pixlyzer_data(
'1.20.3-pre4', 'blocks')
+ burger_data = lib.extract.get_burger_data_for_version(version_id)
block_states_report = lib.extract.get_block_states_report(version_id)
registries = lib.extract.get_registries_report(version_id)
ordered_blocks = lib.code.blocks.get_ordered_blocks(registries)
lib.code.blocks.generate_blocks(
- block_states_report, pixlyzer_block_datas, ordered_blocks)
+ block_states_report, pixlyzer_block_datas, ordered_blocks, burger_data)
lib.code.shapes.generate_block_shapes(
pixlyzer_block_datas, shape_datas['shapes'], shape_datas['aabbs'], block_states_report)
diff --git a/codegen/lib/code/blocks.py b/codegen/lib/code/blocks.py
index 2733093b..181ce774 100755
--- a/codegen/lib/code/blocks.py
+++ b/codegen/lib/code/blocks.py
@@ -12,13 +12,15 @@ BLOCKS_RS_DIR = get_dir_location('../azalea-block/src/generated.rs')
# - Block: Has properties and states.
-def generate_blocks(blocks_report: dict, pixlyzer_block_datas: dict, ordered_blocks: list[str]):
+def generate_blocks(blocks_report: dict, pixlyzer_block_datas: dict, ordered_blocks: list[str], burger_data: dict):
with open(BLOCKS_RS_DIR, 'r') as f:
existing_code = f.read().splitlines()
new_make_block_states_macro_code = []
new_make_block_states_macro_code.append('make_block_states! {')
+ burger_block_datas = burger_data[0]['blocks']['block']
+
# Find properties
properties = {}
@@ -77,6 +79,7 @@ def generate_blocks(blocks_report: dict, pixlyzer_block_datas: dict, ordered_blo
for block_id in ordered_blocks:
block_data_report = blocks_report['minecraft:' + block_id]
block_data_pixlyzer = pixlyzer_block_datas.get(f'minecraft:{block_id}', {})
+ block_data_burger = burger_block_datas.get(block_id, {})
default_property_variants: dict[str, str] = {}
for state in block_data_report['states']:
@@ -129,6 +132,14 @@ def generate_blocks(blocks_report: dict, pixlyzer_block_datas: dict, ordered_blo
friction = block_data_pixlyzer.get('friction')
if friction != None:
behavior_constructor += f'.friction({friction})'
+
+ force_solid = None
+ if block_data_burger.get('force_solid_on'):
+ force_solid = 'true'
+ elif block_data_burger.get('force_solid_off'):
+ force_solid = 'false'
+ if force_solid != None:
+ behavior_constructor += f'.force_solid({force_solid})'
# TODO: use burger to generate the blockbehavior
new_make_block_states_macro_code.append(
diff --git a/codegen/lib/extract.py b/codegen/lib/extract.py
index 4119ad55..c62b2b99 100755
--- a/codegen/lib/extract.py
+++ b/codegen/lib/extract.py
@@ -1,7 +1,7 @@
# Extracting data from the Minecraft jars
from typing import TYPE_CHECKING
-from lib.download import get_server_jar, get_burger, get_client_jar, get_pixlyzer, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions
+from lib.download import get_mappings_for_version, get_server_jar, get_burger, get_client_jar, get_pixlyzer, get_yarn_data, get_fabric_api_versions, get_fabric_loader_versions
from lib.utils import get_dir_location, to_camel_case, upper_first_letter
from zipfile import ZipFile
import subprocess
@@ -53,19 +53,8 @@ python_command = None
def determine_python_command():
- global python_command
- if python_command:
- return python_command
-
- def try_python_command(version):
- return os.system(f'{version} --version') == 0
-
- for version in (sys.executable, 'python3.9', 'python3.8', 'python3', 'python'):
- if try_python_command(version):
- python_command = version
- return version
- raise Exception(
- 'Couldn\'t determine python command to use to run burger with!')
+ return 'venv/bin/python'
+
def run_python_command_and_download_deps(command):
@@ -105,10 +94,14 @@ def get_burger_data_for_version(version_id: str):
if not os.path.exists(get_dir_location(f'__cache__/burger-{version_id}.json')):
get_burger()
get_client_jar(version_id)
+ get_mappings_for_version(version_id)
print('\033[92mRunning Burger...\033[m')
run_python_command_and_download_deps(
- f'cd {get_dir_location("__cache__/Burger")} && {determine_python_command()} munch.py {get_dir_location("__cache__")}/client-{version_id}.jar --output {get_dir_location("__cache__")}/burger-{version_id}.json'
+ f'cd {get_dir_location("__cache__/Burger")} && '\
+ f'{determine_python_command()} munch.py {get_dir_location("__cache__")}/client-{version_id}.jar '\
+ f'--output {get_dir_location("__cache__")}/burger-{version_id}.json '\
+ f'--mappings {get_dir_location("__cache__")}/mappings-{version_id}.txt'
)
with open(get_dir_location(f'__cache__/burger-{version_id}.json'), 'r') as f:
return json.load(f)
diff --git a/codegen/lib/mappings.py b/codegen/lib/mappings.py
index 22624fac..9c39fc2b 100755
--- a/codegen/lib/mappings.py
+++ b/codegen/lib/mappings.py
@@ -78,7 +78,6 @@ class Mappings:
return self.classes[obfuscated_class_name]
def get_method(self, obfuscated_class_name, obfuscated_method_name, obfuscated_signature):
- # print(obfuscated_class_name, self.methods[obfuscated_class_name])
return self.methods[obfuscated_class_name][f'{obfuscated_method_name}({obfuscated_signature})']
def get_field_type(self, obfuscated_class_name, obfuscated_field_name) -> str: