steel_core/entity/entities/objects/technical/
marker.rs1use crate::entity::damage::DamageSource;
2use crate::entity::{Entity, EntityBase, EntityBaseLoad};
3use crate::world::World;
4use glam::DVec3;
5use std::sync::Arc;
6use std::sync::Weak;
7use steel_macros::entity_behavior;
8use steel_registry::blocks::behavior::PushReaction;
9use steel_registry::entity_type::EntityTypeRef;
10use steel_utils::{DowncastType, DowncastTypeKey};
11use uuid::Uuid;
12
13#[entity_behavior(class = "Marker")]
17pub struct MarkerEntity {
18 base: EntityBase,
19 entity_type: EntityTypeRef,
20}
21
22unsafe impl DowncastType for MarkerEntity {
24 const TYPE_KEY: DowncastTypeKey = DowncastTypeKey::new("steel:entity/marker");
25}
26
27impl MarkerEntity {
28 #[must_use]
30 pub fn new(entity_type: EntityTypeRef, id: i32, position: DVec3, world: Weak<World>) -> Self {
31 Self {
32 base: EntityBase::new(id, position, entity_type.dimensions, world),
33 entity_type,
34 }
35 }
36
37 #[must_use]
39 pub fn with_uuid(
40 entity_type: EntityTypeRef,
41 id: i32,
42 position: DVec3,
43 uuid: Uuid,
44 world: Weak<World>,
45 ) -> Self {
46 Self {
47 base: EntityBase::with_uuid(id, uuid, position, entity_type.dimensions, world),
48 entity_type,
49 }
50 }
51
52 #[must_use]
54 pub fn from_saved(entity_type: EntityTypeRef, load: EntityBaseLoad) -> Self {
55 Self {
56 base: EntityBase::from_load(load, entity_type.dimensions),
57 entity_type,
58 }
59 }
60}
61
62impl Entity for MarkerEntity {
63 fn base(&self) -> &EntityBase {
64 &self.base
65 }
66
67 fn entity_type(&self) -> EntityTypeRef {
68 self.entity_type
69 }
70
71 fn is_ignoring_block_triggers(&self) -> bool {
72 true
73 }
74
75 fn piston_push_reaction(&self) -> PushReaction {
76 PushReaction::IgnoreEntity
77 }
78
79 fn can_add_passenger(&self, _passenger: &dyn Entity) -> bool {
80 false
81 }
82
83 fn could_accept_passenger(&self) -> bool {
84 false
85 }
86
87 fn tick(self: Arc<Self>) {}
88
89 fn no_physics(&self) -> bool {
90 true
91 }
92
93 fn hurt(&self, _world: &World, _source: &DamageSource, _amount: f32) -> bool {
94 false
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use crate::entity::damage::DamageSource;
101 use crate::entity::entities::{MarkerEntity, PigEntity};
102 use crate::entity::{Entity, SharedEntity, start_riding_entities};
103 use crate::test_support::test_world;
104 use glam::DVec3;
105 use std::sync::Arc;
106 use steel_registry::{vanilla_damage_types, vanilla_entities};
107
108 const TEST_POSITION: DVec3 = DVec3::new(-8.0, 128.0, 4.0);
109
110 #[test]
111 fn markers_cannot_get_hurt() {
112 let world = test_world();
113 let marker = MarkerEntity::new(
114 &vanilla_entities::MARKER,
115 0,
116 TEST_POSITION,
117 Arc::downgrade(world),
118 );
119 assert!(!marker.hurt(
120 world,
121 &DamageSource::environment(&vanilla_damage_types::GENERIC),
122 5.0
123 ));
124 }
125
126 #[test]
127 fn markers_cannot_fall() {
128 let world = test_world();
129 let marker = Arc::new(MarkerEntity::new(
130 &vanilla_entities::MARKER,
131 0,
132 TEST_POSITION,
133 Arc::downgrade(world),
134 ));
135 for _ in 0..100 {
136 Arc::clone(&marker).tick();
137 }
138 assert_eq!(marker.position(), TEST_POSITION);
139 }
140
141 #[test]
142 fn markers_cannot_have_passenger() {
143 let world = test_world();
144 let marker: SharedEntity = Arc::new(MarkerEntity::new(
145 &vanilla_entities::MARKER,
146 0,
147 TEST_POSITION,
148 Arc::downgrade(world),
149 ));
150 let passenger: SharedEntity = Arc::new(PigEntity::new(
151 &vanilla_entities::PIG,
152 1,
153 TEST_POSITION,
154 Arc::downgrade(world),
155 ));
156 assert!(!start_riding_entities(&passenger, &marker));
157 }
158}