Skip to main content

Position

Struct Position 

Source
pub struct Position(/* private fields */);
Expand description

The position of the entity right now.

If this is being used as an ECS component then you are free to modify it, because there are systems that will update the indexes automatically.

Its value is set to a default of [Vec3::ZERO] when it receives the login packet, its true position may be set ticks later.

Implementations§

Source§

impl Position

Source

pub fn new(pos: Vec3) -> Self

Methods from Deref<Target = Vec3>§

pub fn with_delta(&self, delta: &impl PositionDeltaTrait) -> Vec3

pub fn normalize(&self) -> Vec3

pub fn multiply(&self, x: f64, y: f64, z: f64) -> Vec3

pub fn scale(&self, amount: f64) -> Vec3

pub const ZERO: Vec3

pub fn length_squared(&self) -> f64

Get the distance of this vector to the origin by doing x^2 + y^2 + z^2.

pub fn horizontal_distance_squared(&self) -> f64

pub fn down(&self, y: f64) -> Vec3

Return a new instance of this position with the y coordinate decreased by the given number.

pub fn up(&self, y: f64) -> Vec3

Return a new instance of this position with the y coordinate increased by the given number.

Examples found in repository?
azalea/examples/testbot/commands/movement.rs (line 28)
13pub fn register(commands: &mut Dispatcher) {
14    commands.register(
15        literal("goto")
16            .executes(|ctx: &Ctx| {
17                let source = ctx.source.lock();
18                println!("got goto");
19                // look for the sender
20                let Some(entity) = source.entity() else {
21                    source.reply("I can't see you!");
22                    return Ok(0);
23                };
24                let position = entity.position()?;
25                source.reply("ok");
26                source
27                    .bot
28                    .start_goto(BlockPosGoal(BlockPos::from(position.up(0.5))));
29                Ok(1)
30            })
31            .then(literal("xz").then(argument("x", integer()).then(
32                argument("z", integer()).executes(|ctx: &Ctx| {
33                    let source = ctx.source.lock();
34                    let x = get_integer(ctx, "x").unwrap();
35                    let z = get_integer(ctx, "z").unwrap();
36                    println!("goto xz {x} {z}");
37                    source.reply("ok");
38                    source.bot.start_goto(XZGoal { x, z });
39                    Ok(1)
40                }),
41            )))
42            .then(literal("radius").then(argument("radius", float()).then(
43                argument("x", integer()).then(argument("y", integer()).then(
44                    argument("z", integer()).executes(|ctx: &Ctx| {
45                        let source = ctx.source.lock();
46                        let radius = get_float(ctx, "radius").unwrap();
47                        let x = get_integer(ctx, "x").unwrap();
48                        let y = get_integer(ctx, "y").unwrap();
49                        let z = get_integer(ctx, "z").unwrap();
50                        println!("goto radius {radius}, position: {x} {y} {z}");
51                        source.reply("ok");
52                        source.bot.start_goto(RadiusGoal {
53                            pos: BlockPos::new(x, y, z).center(),
54                            radius,
55                        });
56                        Ok(1)
57                    }),
58                )),
59            )))
60            .then(argument("x", integer()).then(argument("y", integer()).then(
61                argument("z", integer()).executes(|ctx: &Ctx| {
62                    let source = ctx.source.lock();
63                    let x = get_integer(ctx, "x").unwrap();
64                    let y = get_integer(ctx, "y").unwrap();
65                    let z = get_integer(ctx, "z").unwrap();
66                    println!("goto xyz {x} {y} {z}");
67                    source.reply("ok");
68                    source.bot.start_goto(BlockPosGoal(BlockPos::new(x, y, z)));
69                    Ok(1)
70                }),
71            ))),
72    );
73
74    commands.register(literal("follow").executes(|ctx: &Ctx| {
75        let source = ctx.source.lock();
76        println!("got follow");
77        // look for the sender
78        let Some(entity) = source.entity() else {
79            source.reply("I can't see you!");
80            return Ok(0);
81        };
82        source.reply("ok");
83        *source.state.following_entity.lock() = Some(entity);
84        Ok(1)
85    }));
86
87    commands.register(literal("down").executes(|ctx: &Ctx| {
88        let source = ctx.source.clone();
89        let bot = source.lock().bot.clone();
90        let position = BlockPos::from(bot.position()?);
91        tokio::spawn(async move {
92            source.lock().reply("mining...");
93            bot.mine(position.down(1)).await;
94            source.lock().reply("done");
95        });
96        Ok(1)
97    }));
98
99    commands.register(
100        literal("look")
101            .executes(|ctx: &Ctx| {
102                // look for the sender
103                let source = ctx.source.lock();
104                let Some(entity) = source.entity() else {
105                    source.reply("I can't see you!");
106                    return Ok(0);
107                };
108                let eye_position = entity.eye_position()?;
109                source.bot.look_at(eye_position);
110                Ok(1)
111            })
112            .then(argument("x", integer()).then(argument("y", integer()).then(
113                argument("z", integer()).executes(|ctx: &Ctx| {
114                    let pos = BlockPos::new(
115                        get_integer(ctx, "x").unwrap(),
116                        get_integer(ctx, "y").unwrap(),
117                        get_integer(ctx, "z").unwrap(),
118                    );
119                    println!("{pos:?}");
120                    let source = ctx.source.lock();
121                    source.bot.look_at(pos.center());
122                    Ok(1)
123                }),
124            ))),
125    );
126
127    fn walk_command(ctx: &Ctx, direction: WalkDirection) -> eyre::Result<i32> {
128        let mut seconds = get_float(ctx, "seconds").unwrap();
129        let source = ctx.source.lock();
130        let bot = source.bot.clone();
131
132        if seconds < 0. {
133            bot.walk(direction.opposite());
134            seconds = -seconds;
135        } else {
136            bot.walk(direction);
137        }
138
139        tokio::spawn(async move {
140            tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
141            bot.walk(WalkDirection::None);
142        });
143        source.reply(format!("ok, walking {direction:?} for {seconds} seconds"));
144        Ok(1)
145    }
146
147    commands.register(
148        literal("walk").then(
149            argument("seconds", float())
150                .executes(|ctx: &Ctx| walk_command(ctx, WalkDirection::Forward)),
151        ),
152    );
153    commands.register(literal("left").then(
154        argument("seconds", float()).executes(|ctx: &Ctx| walk_command(ctx, WalkDirection::Left)),
155    ));
156    commands.register(literal("right").then(
157        argument("seconds", float()).executes(|ctx: &Ctx| walk_command(ctx, WalkDirection::Left)),
158    ));
159    commands.register(
160        literal("sprint").then(argument("seconds", float()).executes(|ctx: &Ctx| {
161            let seconds = get_float(ctx, "seconds").unwrap();
162            let source = ctx.source.lock();
163            let bot = source.bot.clone();
164            bot.sprint(SprintDirection::Forward);
165            tokio::spawn(async move {
166                tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
167                bot.walk(WalkDirection::None);
168            });
169            source.reply(format!("ok, sprinting for {seconds} seconds"));
170            Ok(1)
171        })),
172    );
173
174    commands.register(literal("north").executes(|ctx: &Ctx| {
175        let source = ctx.source.lock();
176        source.bot.set_direction(180., 0.)?;
177        source.reply("ok");
178        Ok(1)
179    }));
180    commands.register(literal("south").executes(|ctx: &Ctx| {
181        let source = ctx.source.lock();
182        source.bot.set_direction(0., 0.)?;
183        source.reply("ok");
184        Ok(1)
185    }));
186    commands.register(literal("east").executes(|ctx: &Ctx| {
187        let source = ctx.source.lock();
188        source.bot.set_direction(-90., 0.)?;
189        source.reply("ok");
190        Ok(1)
191    }));
192    commands.register(literal("west").executes(|ctx: &Ctx| {
193        let source = ctx.source.lock();
194        source.bot.set_direction(90., 0.)?;
195        source.reply("ok");
196        Ok(1)
197    }));
198    commands.register(
199        literal("jump")
200            .executes(|ctx: &Ctx| {
201                let source = ctx.source.lock();
202                source.bot.jump();
203                source.reply("ok");
204                Ok(1)
205            })
206            .then(argument("enabled", bool()).executes(|ctx: &Ctx| {
207                let jumping = get_bool(ctx, "enabled").unwrap();
208                let source = ctx.source.lock();
209                source.bot.set_jumping(jumping)?;
210                Ok(1)
211            })),
212    );
213
214    let sneak = |ctx: &Ctx| {
215        let source = ctx.source.lock();
216        source.bot.set_crouching(!source.bot.crouching())?;
217        source.reply("ok");
218        Ok(1)
219    };
220    let sneak_enabled = argument("enabled", bool()).executes(|ctx: &Ctx| {
221        let sneaking = get_bool(ctx, "enabled").unwrap();
222        let source = ctx.source.lock();
223        source.bot.set_crouching(sneaking)?;
224        Ok(1)
225    });
226    commands.register(literal("sneak").executes(sneak).then(sneak_enabled.clone()));
227    commands.register(literal("crouch").executes(sneak).then(sneak_enabled));
228
229    commands.register(literal("stop").executes(|ctx: &Ctx| {
230        let source = ctx.source.lock();
231        source.bot.stop_pathfinding();
232        source.reply("ok");
233        *source.state.following_entity.lock() = None;
234        Ok(1)
235    }));
236    commands.register(literal("forcestop").executes(|ctx: &Ctx| {
237        let source = ctx.source.lock();
238        source.bot.force_stop_pathfinding();
239        source.reply("ok");
240        *source.state.following_entity.lock() = None;
241        Ok(1)
242    }));
243}

pub fn north(&self, z: f64) -> Vec3

Return a new instance of this position with the z coordinate subtracted by the given number.

pub fn east(&self, x: f64) -> Vec3

Return a new instance of this position with the x coordinate increased by the given number.

pub fn south(&self, z: f64) -> Vec3

Return a new instance of this position with the z coordinate increased by the given number.

pub fn west(&self, x: f64) -> Vec3

Return a new instance of this position with the x coordinate subtracted by the given number.

pub fn dot(&self, other: Vec3) -> f64

pub fn cross(&self, other: Vec3) -> Vec3

pub fn min(&self, other: Vec3) -> Vec3

Make a new position with the lower coordinates for each axis.

pub fn max(&self, other: Vec3) -> Vec3

Make a new position with the higher coordinates for each axis.

pub fn xz(&self) -> Vec3

Replace the Y with 0.

pub fn with_x(&self, x: f64) -> Vec3

pub fn with_y(&self, y: f64) -> Vec3

pub fn with_z(&self, z: f64) -> Vec3

pub fn length(&self) -> f64

Get the distance of this vector to the origin by doing sqrt(x^2 + y^2 + z^2).

pub fn to_block_pos_floor(&self) -> BlockPos

pub fn to_block_pos_ceil(&self) -> BlockPos

pub fn closer_than(&self, other: Vec3, range: f64) -> bool

Whether the distance between this point and other is less than range.

Trait Implementations§

Source§

impl Clone for Position

Source§

fn clone(&self) -> Position

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Component for Position
where Self: Send + Sync + 'static,

Source§

const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::Table

A constant indicating the storage type used for this component.
Source§

type Mutability = Mutable

A marker type to assist Bevy with determining if this component is mutable, or immutable. Mutable components will have [Component<Mutability = Mutable>], while immutable components will instead have [Component<Mutability = Immutable>]. Read more
Source§

fn register_required_components( _requiree: ComponentId, required_components: &mut RequiredComponentsRegistrator<'_, '_>, )

Registers required components. Read more
Source§

fn clone_behavior() -> ComponentCloneBehavior

Called when registering this component, allowing to override clone function (or disable cloning altogether) for this component. Read more
Source§

fn relationship_accessor() -> Option<ComponentRelationshipAccessor<Self>>

Returns [ComponentRelationshipAccessor] required for working with relationships in dynamic contexts. Read more
§

fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_add [ComponentHook] for this [Component] if one is defined.
§

fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_insert [ComponentHook] for this [Component] if one is defined.
§

fn on_replace() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_replace [ComponentHook] for this [Component] if one is defined.
§

fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_remove [ComponentHook] for this [Component] if one is defined.
§

fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_despawn [ComponentHook] for this [Component] if one is defined.
§

fn map_entities<E>(_this: &mut Self, _mapper: &mut E)
where E: EntityMapper,

Maps the entities on this component using the given [EntityMapper]. This is used to remap entities in contexts like scenes and entity cloning. When deriving [Component], this is populated by annotating fields containing entities with #[entities] Read more
Source§

impl Copy for Position

Source§

impl Debug for Position

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Position

Source§

fn default() -> Position

Returns the “default value” for a type. Read more
Source§

impl Deref for Position

Source§

type Target = Vec3

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl DerefMut for Position

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl From<&Position> for BlockPos

Source§

fn from(value: &Position) -> Self

Converts to this type from the input type.
Source§

impl From<&Position> for ChunkPos

Source§

fn from(value: &Position) -> Self

Converts to this type from the input type.
Source§

impl From<&Position> for Vec3

Source§

fn from(value: &Position) -> Self

Converts to this type from the input type.
Source§

impl From<Position> for BlockPos

Source§

fn from(value: Position) -> Self

Converts to this type from the input type.
Source§

impl From<Position> for ChunkPos

Source§

fn from(value: Position) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for Position

Source§

fn eq(&self, other: &Position) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for Position

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<C> Bundle for C
where C: Component,

§

fn component_ids( components: &mut ComponentsRegistrator<'_>, ) -> impl Iterator<Item = ComponentId> + use<C>

§

fn get_component_ids( components: &Components, ) -> impl Iterator<Item = Option<ComponentId>>

Return a iterator over this [Bundle]’s component ids. This will be None if the component has not been registered.
§

impl<C> BundleFromComponents for C
where C: Component,

§

unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> C
where F: for<'a> FnMut(&'a mut T) -> OwningPtr<'a>,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> ConditionalSend for T
where T: Send,

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSend for T
where T: Any + Send,

§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

impl<C> DynamicBundle for C
where C: Component,

§

type Effect = ()

An operation on the entity that happens after inserting this bundle.
§

unsafe fn get_components( ptr: MovingPtr<'_, C>, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect

Moves the components out of the bundle. Read more
§

unsafe fn apply_effect( _ptr: MovingPtr<'_, MaybeUninit<C>>, _entity: &mut EntityWorldMut<'_>, )

Applies the after-effects of spawning this bundle. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromWorld for T
where T: Default,

§

fn from_world(_world: &mut World) -> T

Creates Self using default().

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> IntoResult<T> for T

§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
§

impl<A> Is for A
where A: Any,

§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

§

fn clone_type_data(&self) -> Box<dyn TypeData>

Creates a type-erased clone of this value.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more