Skip to content

Commit

Permalink
Climbing (#121)
Browse files Browse the repository at this point in the history
* start implementing climbing

* fix tests

* fix bots running at lower tick rate
  • Loading branch information
mat-1 authored Dec 10, 2023
1 parent f15f032 commit 348c71b
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 61 deletions.
21 changes: 5 additions & 16 deletions azalea-block/azalea-block-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,17 +327,11 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
}

property_enums.extend(quote! {
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum #property_struct_name {
#property_enum_variants
}

// impl Property for #property_struct_name {
// type Value = Self;

// fn try_from_block_state
// }

impl From<u32> for #property_struct_name {
fn from(value: u32) -> Self {
match value {
Expand All @@ -354,13 +348,9 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
property_variant_types = vec!["true".to_string(), "false".to_string()];

property_enums.extend(quote! {
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct #property_struct_name(pub bool);

// impl Property for #property_struct_name {
// type Value = bool;
// }

impl From<u32> for #property_struct_name {
fn from(value: u32) -> Self {
match value {
Expand Down Expand Up @@ -542,10 +532,9 @@ pub fn make_block_states(input: TokenStream) -> TokenStream {
// add to properties_to_state_ids
let property_variants = properties_to_state_ids
.entry(property_value_name_ident.to_string())
.or_insert_with(Vec::new);
let property_variant_data = property_variants
.iter_mut()
.find(|v| v.ident.to_string() == variant.to_string());
.or_default();
let property_variant_data =
property_variants.iter_mut().find(|v| v.ident == variant);
if let Some(property_variant_data) = property_variant_data {
property_variant_data.block_state_ids.push(state_id);
} else {
Expand Down
6 changes: 6 additions & 0 deletions azalea-block/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ impl From<FluidState> for BlockState {
}
}

impl From<BlockState> for azalea_registry::Block {
fn from(value: BlockState) -> Self {
Box::<dyn Block>::from(value).as_registry_block()
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
6 changes: 5 additions & 1 deletion azalea-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,11 @@ async fn run_schedule_loop(
.map(|last_tick| last_tick.elapsed() > Duration::from_millis(50))
.unwrap_or(true)
{
last_tick = Some(Instant::now());
if let Some(last_tick) = &mut last_tick {
*last_tick += Duration::from_millis(50);
} else {
last_tick = Some(Instant::now());
}
ecs.run_schedule(GameTick);
}

Expand Down
2 changes: 1 addition & 1 deletion azalea-entity/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
19 changes: 18 additions & 1 deletion azalea-entity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand All @@ -246,6 +255,9 @@ impl Physics {
dimensions,

has_impulse: false,

horizontal_collision: false,
vertical_collision: false,
}
}
}
Expand Down Expand Up @@ -311,6 +323,7 @@ pub struct EntityBundle {
pub attributes: Attributes,
pub jumping: Jumping,
pub fluid_on_eyes: FluidOnEyes,
pub on_climbable: OnClimbable,
}

impl EntityBundle {
Expand Down Expand Up @@ -346,6 +359,7 @@ impl EntityBundle {

jumping: Jumping(false),
fluid_on_eyes: FluidOnEyes(azalea_registry::Fluid::Empty),
on_climbable: OnClimbable(false),
}
}
}
Expand Down Expand Up @@ -373,6 +387,9 @@ impl FluidOnEyes {
}
}

#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
pub struct OnClimbable(bool);

// #[cfg(test)]
// mod tests {
// use super::*;
Expand Down
71 changes: 70 additions & 1 deletion azalea-entity/src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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;
Expand Down Expand Up @@ -48,6 +50,7 @@ impl Plugin for EntityPlugin {
add_dead,
clamp_look_direction,
update_fluid_on_eyes,
update_on_climbable,
),
),
)
Expand Down Expand Up @@ -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)]
Expand Down
11 changes: 7 additions & 4 deletions azalea-physics/src/collision/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub fn move_colliding(
_mover_type: &MoverType,
movement: &Vec3,
world: &Instance,
mut position: Mut<azalea_entity::Position>,
position: &mut Mut<azalea_entity::Position>,
physics: &mut azalea_entity::Physics,
) -> Result<(), MoveEntityError> {
// TODO: do all these
Expand Down Expand Up @@ -175,8 +175,8 @@ pub fn move_colliding(
}
};

if new_pos != **position {
**position = new_pos;
if new_pos != ***position {
***position = new_pos;
}
}

Expand All @@ -185,11 +185,14 @@ pub fn move_colliding(
let horizontal_collision = x_collision || z_collision;
let vertical_collision = movement.y != collide_result.y;
let on_ground = vertical_collision && movement.y < 0.;

physics.horizontal_collision = horizontal_collision;
physics.vertical_collision = vertical_collision;
physics.on_ground = on_ground;

// TODO: minecraft checks for a "minor" horizontal collision here

let _block_pos_below = azalea_entity::on_pos_legacy(&world.chunks, &position);
let _block_pos_below = azalea_entity::on_pos_legacy(&world.chunks, position);
// let _block_state_below = self
// .world
// .get_block_state(&block_pos_below)
Expand Down
Loading

0 comments on commit 348c71b

Please sign in to comment.