steel_core/entity/entities/
block_display.rs1use std::sync::Weak;
7
8use glam::DVec3;
9use simdnbt::borrow::NbtCompound as BorrowedNbtCompoundView;
10use simdnbt::owned::NbtCompound;
11use steel_macros::entity_behavior;
12use steel_registry::entity_type::EntityTypeRef;
13use steel_registry::vanilla_entity_data::BlockDisplayEntityData;
14use steel_utils::BlockStateId;
15use steel_utils::locks::SyncMutex;
16use steel_utils::{DowncastType, DowncastTypeKey};
17use uuid::Uuid;
18
19use crate::entity::{Entity, EntityBase, EntityBaseLoad, EntitySyncedData};
20use crate::world::World;
21
22#[entity_behavior(class = "BlockDisplay")]
28pub struct BlockDisplayEntity {
29 base: EntityBase,
31 entity_type: EntityTypeRef,
33 entity_data: SyncMutex<BlockDisplayEntityData>,
35}
36
37unsafe impl DowncastType for BlockDisplayEntity {
39 const TYPE_KEY: DowncastTypeKey = DowncastTypeKey::new("steel:entity/block_display");
40}
41
42impl BlockDisplayEntity {
43 #[must_use]
47 pub fn new(entity_type: EntityTypeRef, id: i32, position: DVec3, world: Weak<World>) -> Self {
48 Self {
49 base: EntityBase::new(id, position, entity_type.dimensions, world),
50 entity_type,
51 entity_data: SyncMutex::new(BlockDisplayEntityData::new()),
52 }
53 }
54
55 #[must_use]
59 pub fn with_uuid(
60 entity_type: EntityTypeRef,
61 id: i32,
62 position: DVec3,
63 uuid: Uuid,
64 world: Weak<World>,
65 ) -> Self {
66 Self {
67 base: EntityBase::with_uuid(id, uuid, position, entity_type.dimensions, world),
68 entity_type,
69 entity_data: SyncMutex::new(BlockDisplayEntityData::new()),
70 }
71 }
72
73 #[must_use]
78 pub fn from_saved(entity_type: EntityTypeRef, load: EntityBaseLoad) -> Self {
79 Self {
80 base: EntityBase::from_load(load, entity_type.dimensions),
81 entity_type,
82 entity_data: SyncMutex::new(BlockDisplayEntityData::new()),
83 }
84 }
85
86 pub const fn entity_data(&self) -> &SyncMutex<BlockDisplayEntityData> {
88 &self.entity_data
89 }
90
91 pub fn set_block_state_id(&self, id: BlockStateId) {
93 self.entity_data.lock().block_state.set(id);
94 }
95}
96
97impl Entity for BlockDisplayEntity {
98 fn base(&self) -> &EntityBase {
99 &self.base
100 }
101
102 fn entity_type(&self) -> EntityTypeRef {
103 self.entity_type
104 }
105
106 fn synced_data(&self) -> Option<&dyn EntitySyncedData> {
107 Some(&self.entity_data)
108 }
109
110 fn is_ignoring_block_triggers(&self) -> bool {
111 true
112 }
113
114 fn save_additional(&self, nbt: &mut NbtCompound) {
115 let block_state_id = *self.entity_data.lock().block_state.get();
117 nbt.insert("block_state", i32::from(block_state_id.0));
118 }
119
120 fn load_additional(&self, nbt: BorrowedNbtCompoundView<'_, '_>) {
121 if let Some(state_id) = nbt.int("block_state") {
123 self.entity_data
124 .lock()
125 .block_state
126 .set(BlockStateId(state_id as u16));
127 }
128 }
129}