aboutsummaryrefslogtreecommitdiff
path: root/azalea-entity/src/plugin/components.rs
blob: eaeeb0d0369cdb84be55915f3296fb5c374382da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
use azalea_block::fluid_state::FluidKind;
use azalea_core::position::{BlockPos, ChunkPos, Vec3};
use azalea_registry::builtin::EntityKind;
use azalea_world::WorldName;
use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
use uuid::Uuid;

use crate::{
    ActiveEffects, Attributes, EntityUuid, FluidOnEyes, LookDirection, Physics, Position,
    dimensions::EntityDimensions, indexing::EntityChunkPos,
};

/// A bundle of components that every entity has.
///
/// This doesn't contain metadata; that has to be added separately.
#[derive(Bundle)]
pub struct EntityBundle {
    pub kind: EntityKindComponent,
    pub uuid: EntityUuid,
    pub world_name: WorldName,
    pub position: Position,
    pub last_sent_position: LastSentPosition,

    pub chunk_pos: EntityChunkPos,

    pub physics: Physics,
    pub direction: LookDirection,
    pub dimensions: EntityDimensions,
    pub attributes: Attributes,
    pub jumping: Jumping,
    pub crouching: Crouching,
    pub fluid_on_eyes: FluidOnEyes,
    pub on_climbable: OnClimbable,
    pub active_effects: ActiveEffects,
}

impl EntityBundle {
    pub fn new(uuid: Uuid, pos: Vec3, kind: EntityKind, world_name: WorldName) -> Self {
        let dimensions = EntityDimensions::from(kind);

        Self {
            kind: EntityKindComponent(kind),
            uuid: EntityUuid(uuid),
            world_name,
            position: Position(pos),
            chunk_pos: EntityChunkPos(ChunkPos::from(&pos)),
            last_sent_position: LastSentPosition(pos),
            physics: Physics::new(&dimensions, pos),
            dimensions,
            direction: LookDirection::default(),

            attributes: Attributes::new(EntityKind::Player),

            jumping: Jumping(false),
            crouching: Crouching(false),
            fluid_on_eyes: FluidOnEyes(FluidKind::Empty),
            on_climbable: OnClimbable(false),
            active_effects: ActiveEffects::default(),
        }
    }
}

/// Marker component for entities that are dead.
///
/// "Dead" means that the entity has 0 health.
#[derive(Clone, Component, Copy, Default)]
pub struct Dead;

/// A component NewType for [`EntityKind`].
///
/// Most of the time, you should be using `azalea_registry::EntityKind`
/// directly instead.
#[derive(Clone, Component, Copy, Debug, Deref, PartialEq)]
pub struct EntityKindComponent(pub EntityKind);

/// A marker component that signifies that this entity is "local" and shouldn't
/// be updated by other clients.
///
/// If this is for a client then all of our clients will have this.
///
/// This component is not removed from clients when they disconnect.
#[derive(Clone, Component, Copy, Debug, Default)]
pub struct LocalEntity;

impl FluidOnEyes {
    pub fn new(fluid: FluidKind) -> Self {
        Self(fluid)
    }
}

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

/// A component that indicates whether the player is currently sneaking.
///
/// If the entity is a player but isn't a local player, then this is just a
/// shortcut for checking if the [`Pose`] is `Crouching`.
///
/// If you need to modify this value, use
/// `azalea_client::PhysicsState::trying_to_crouch` or `Client::set_crouching`
/// instead.
///
/// [`Pose`]: crate::data::Pose
#[derive(Clone, Component, Copy, Default, Deref, DerefMut)]
pub struct Crouching(bool);

/// A component that indicates whether the client has loaded.
///
/// This is updated by a system in `azalea-client`.
#[derive(Component)]
pub struct HasClientLoaded;

/// The second most recent position of the entity that was sent over the
/// network.
///
/// This is currently only updated for our own local player entities.
#[derive(Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq)]
pub struct LastSentPosition(Vec3);
impl From<&LastSentPosition> for Vec3 {
    fn from(value: &LastSentPosition) -> Self {
        value.0
    }
}
impl From<LastSentPosition> for ChunkPos {
    fn from(value: LastSentPosition) -> Self {
        ChunkPos::from(&value.0)
    }
}
impl From<LastSentPosition> for BlockPos {
    fn from(value: LastSentPosition) -> Self {
        BlockPos::from(&value.0)
    }
}
impl From<&LastSentPosition> for ChunkPos {
    fn from(value: &LastSentPosition) -> Self {
        ChunkPos::from(value.0)
    }
}
impl From<&LastSentPosition> for BlockPos {
    fn from(value: &LastSentPosition) -> Self {
        BlockPos::from(value.0)
    }
}

/// A component for entities that can jump.
///
/// If this is true, the entity will try to jump every tick. It's equivalent to
/// the space key being held in vanilla.
#[derive(Clone, Copy, Component, Debug, Default, Deref, DerefMut, Eq, PartialEq)]
pub struct Jumping(pub bool);