aboutsummaryrefslogtreecommitdiff
path: root/azalea-entity/src
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2023-12-10 00:08:08 -0600
committerGitHub <noreply@github.com>2023-12-10 00:08:08 -0600
commit348c71b97b2dfc45d7412ec33f6131e20592bb14 (patch)
tree2490f6fe8e4d8181a526b66e0397ceea96ec8961 /azalea-entity/src
parentf15f0325c0a9d62f10ea22b891ab7134391b04fb (diff)
downloadazalea-drasl-348c71b97b2dfc45d7412ec33f6131e20592bb14.tar.xz
Climbing (#121)
* start implementing climbing * fix tests * fix bots running at lower tick rate
Diffstat (limited to 'azalea-entity/src')
-rwxr-xr-xazalea-entity/src/data.rs2
-rw-r--r--azalea-entity/src/lib.rs19
-rw-r--r--azalea-entity/src/plugin/mod.rs71
3 files changed, 89 insertions, 3 deletions
diff --git a/azalea-entity/src/data.rs b/azalea-entity/src/data.rs
index 83779b21..b0a05e74 100755
--- a/azalea-entity/src/data.rs
+++ b/azalea-entity/src/data.rs
@@ -134,7 +134,7 @@ pub struct Rotations {
pub z: f32,
}
-#[derive(Clone, Debug, Copy, McBuf, Default, Component)]
+#[derive(Clone, Debug, Copy, McBuf, Default, Component, Eq, PartialEq)]
pub enum Pose {
#[default]
Standing = 0,
diff --git a/azalea-entity/src/lib.rs b/azalea-entity/src/lib.rs
index bf3dfc82..eb5b5b25 100644
--- a/azalea-entity/src/lib.rs
+++ b/azalea-entity/src/lib.rs
@@ -116,8 +116,13 @@ pub fn on_pos(offset: f32, chunk_storage: &ChunkStorage, pos: &Position) -> Bloc
/// The Minecraft UUID of the entity. For players, this is their actual player
/// UUID, and for other entities it's just random.
-#[derive(Component, Deref, DerefMut, Clone, Copy)]
+#[derive(Component, Deref, DerefMut, Clone, Copy, Default)]
pub struct EntityUuid(Uuid);
+impl EntityUuid {
+ pub fn new(uuid: Uuid) -> Self {
+ Self(uuid)
+ }
+}
impl Debug for EntityUuid {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self.0).fmt(f)
@@ -228,6 +233,10 @@ pub struct Physics {
pub bounding_box: AABB,
pub has_impulse: bool,
+
+ pub horizontal_collision: bool,
+ // pub minor_horizontal_collision: bool,
+ pub vertical_collision: bool,
}
impl Physics {
@@ -246,6 +255,9 @@ impl Physics {
dimensions,
has_impulse: false,
+
+ horizontal_collision: false,
+ vertical_collision: false,
}
}
}
@@ -311,6 +323,7 @@ pub struct EntityBundle {
pub attributes: Attributes,
pub jumping: Jumping,
pub fluid_on_eyes: FluidOnEyes,
+ pub on_climbable: OnClimbable,
}
impl EntityBundle {
@@ -346,6 +359,7 @@ impl EntityBundle {
jumping: Jumping(false),
fluid_on_eyes: FluidOnEyes(azalea_registry::Fluid::Empty),
+ on_climbable: OnClimbable(false),
}
}
}
@@ -373,6 +387,9 @@ impl FluidOnEyes {
}
}
+#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
+pub struct OnClimbable(bool);
+
// #[cfg(test)]
// mod tests {
// use super::*;
diff --git a/azalea-entity/src/plugin/mod.rs b/azalea-entity/src/plugin/mod.rs
index 9950e6ba..4b6d9979 100644
--- a/azalea-entity/src/plugin/mod.rs
+++ b/azalea-entity/src/plugin/mod.rs
@@ -3,6 +3,7 @@ mod relative_updates;
use std::collections::HashSet;
+use azalea_block::BlockState;
use azalea_core::position::{BlockPos, ChunkPos, Vec3};
use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId};
use bevy_app::{App, Plugin, PreUpdate, Update};
@@ -11,7 +12,8 @@ use derive_more::{Deref, DerefMut};
use tracing::debug;
use crate::{
- metadata::Health, Dead, EyeHeight, FluidOnEyes, LocalEntity, LookDirection, Physics, Position,
+ metadata::Health, Dead, EyeHeight, FluidOnEyes, LocalEntity, LookDirection, OnClimbable,
+ Physics, Position,
};
use indexing::EntityUuidIndex;
@@ -48,6 +50,7 @@ impl Plugin for EntityPlugin {
add_dead,
clamp_look_direction,
update_fluid_on_eyes,
+ update_on_climbable,
),
),
)
@@ -106,6 +109,72 @@ pub fn update_fluid_on_eyes(
}
}
+pub fn update_on_climbable(
+ mut query: Query<(&mut OnClimbable, &Position, &InstanceName)>,
+ instance_container: Res<InstanceContainer>,
+) {
+ for (mut on_climbable, position, instance_name) in query.iter_mut() {
+ // TODO: there's currently no gamemode component that can be accessed from here,
+ // maybe LocalGameMode should be replaced with two components, maybe called
+ // EntityGameMode and PreviousGameMode?
+
+ // if game_mode == GameMode::Spectator {
+ // continue;
+ // }
+
+ let Some(instance) = instance_container.get(instance_name) else {
+ continue;
+ };
+
+ let instance = instance.read();
+
+ let block_pos = BlockPos::from(position);
+ let block_state_at_feet = instance.get_block_state(&block_pos).unwrap_or_default();
+ let block_at_feet = Box::<dyn azalea_block::Block>::from(block_state_at_feet);
+ let registry_block_at_feet = block_at_feet.as_registry_block();
+
+ **on_climbable = azalea_registry::tags::blocks::CLIMBABLE.contains(&registry_block_at_feet)
+ || (azalea_registry::tags::blocks::TRAPDOORS.contains(&registry_block_at_feet)
+ && is_trapdoor_useable_as_ladder(block_state_at_feet, block_pos, &instance));
+ }
+}
+
+fn is_trapdoor_useable_as_ladder(
+ block_state: BlockState,
+ block_pos: BlockPos,
+ instance: &azalea_world::Instance,
+) -> bool {
+ // trapdoor must be open
+ if !block_state
+ .property::<azalea_block::properties::Open>()
+ .unwrap_or_default()
+ {
+ return false;
+ }
+
+ // block below must be a ladder
+ let block_below = instance
+ .get_block_state(&block_pos.down(1))
+ .unwrap_or_default();
+ let registry_block_below =
+ Box::<dyn azalea_block::Block>::from(block_below).as_registry_block();
+ if registry_block_below != azalea_registry::Block::Ladder {
+ return false;
+ }
+ // and the ladder must be facing the same direction as the trapdoor
+ let ladder_facing = block_below
+ .property::<azalea_block::properties::Facing>()
+ .expect("ladder block must have facing property");
+ let trapdoor_facing = block_state
+ .property::<azalea_block::properties::Facing>()
+ .expect("trapdoor block must have facing property");
+ if ladder_facing != trapdoor_facing {
+ return false;
+ }
+
+ true
+}
+
/// A component that lists all the local player entities that have this entity
/// loaded. If this is empty, the entity will be removed from the ECS.
#[derive(Component, Clone, Deref, DerefMut)]