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