1use std::fmt::{self, Display, Formatter};
2use std::hash::{Hash, Hasher};
3use std::io::{self, Cursor};
4use std::{
5 collections::{HashMap, HashSet},
6 fmt::Debug,
7};
8
9use azalea_block::BlockState;
10use azalea_block::fluid_state::FluidState;
11use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
12use azalea_core::position::{BlockPos, ChunkPos};
13use azalea_core::registry_holder::RegistryHolder;
14use bevy_ecs::{component::Component, entity::Entity};
15use derive_more::{Deref, DerefMut};
16use nohash_hasher::IntMap;
17#[cfg(feature = "serde")]
18use serde::{Deserialize, Serialize};
19
20use crate::{ChunkStorage, PartialChunkStorage};
21
22pub struct PartialInstance {
31 pub chunks: PartialChunkStorage,
32 pub entity_infos: PartialEntityInfos,
35}
36
37impl PartialInstance {
38 pub fn new(chunk_radius: u32, owner_entity: Option<Entity>) -> Self {
39 PartialInstance {
40 chunks: PartialChunkStorage::new(chunk_radius),
41 entity_infos: PartialEntityInfos::new(owner_entity),
42 }
43 }
44}
45
46#[derive(Component, Copy, Clone, Debug, Default, PartialEq, Eq, Deref, DerefMut)]
63#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
64pub struct MinecraftEntityId(pub i32);
65
66impl Hash for MinecraftEntityId {
67 fn hash<H: Hasher>(&self, hasher: &mut H) {
68 hasher.write_i32(self.0);
69 }
70}
71impl nohash_hasher::IsEnabled for MinecraftEntityId {}
72
73impl AzaleaRead for MinecraftEntityId {
76 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
77 i32::azalea_read(buf).map(MinecraftEntityId)
78 }
79}
80impl AzaleaWrite for MinecraftEntityId {
81 fn azalea_write(&self, buf: &mut impl io::Write) -> Result<(), io::Error> {
82 i32::azalea_write(&self.0, buf)
83 }
84}
85impl AzaleaReadVar for MinecraftEntityId {
86 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
87 i32::azalea_read_var(buf).map(MinecraftEntityId)
88 }
89}
90impl AzaleaWriteVar for MinecraftEntityId {
91 fn azalea_write_var(&self, buf: &mut impl io::Write) -> Result<(), io::Error> {
92 i32::azalea_write_var(&self.0, buf)
93 }
94}
95impl Display for MinecraftEntityId {
96 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
97 write!(f, "eid({})", self.0)
98 }
99}
100impl From<i32> for MinecraftEntityId {
101 fn from(id: i32) -> Self {
102 Self(id)
103 }
104}
105impl From<u32> for MinecraftEntityId {
106 fn from(id: u32) -> Self {
107 Self(id as i32)
108 }
109}
110
111#[derive(Debug, Default)]
114pub struct PartialEntityInfos {
115 pub owner_entity: Option<Entity>,
121 pub updates_received: IntMap<MinecraftEntityId, u32>,
127}
128
129impl PartialEntityInfos {
130 pub fn new(owner_entity: Option<Entity>) -> Self {
131 Self {
132 owner_entity,
133 updates_received: IntMap::default(),
134 }
135 }
136}
137
138#[derive(Default, Debug)]
141pub struct Instance {
142 pub chunks: ChunkStorage,
143
144 pub entities_by_chunk: HashMap<ChunkPos, HashSet<Entity>>,
146
147 pub entity_by_id: IntMap<MinecraftEntityId, Entity>,
154
155 pub registries: RegistryHolder,
156}
157
158impl Instance {
159 pub fn get_block_state(&self, pos: &BlockPos) -> Option<BlockState> {
160 self.chunks.get_block_state(pos)
161 }
162
163 pub fn get_fluid_state(&self, pos: &BlockPos) -> Option<FluidState> {
164 self.chunks.get_block_state(pos).map(FluidState::from)
165 }
166
167 pub fn set_block_state(&self, pos: &BlockPos, state: BlockState) -> Option<BlockState> {
168 self.chunks.set_block_state(pos, state)
169 }
170}
171
172impl Debug for PartialInstance {
173 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
174 f.debug_struct("PartialInstance")
175 .field("chunks", &self.chunks)
176 .field("entity_infos", &self.entity_infos)
177 .finish()
178 }
179}
180
181impl Default for PartialInstance {
182 fn default() -> Self {
185 let chunk_storage = PartialChunkStorage::default();
186 let entity_storage = PartialEntityInfos::default();
187 Self {
188 chunks: chunk_storage,
189 entity_infos: entity_storage,
190 }
191 }
192}
193
194impl From<ChunkStorage> for Instance {
195 fn from(chunks: ChunkStorage) -> Self {
198 Self {
199 chunks,
200 entities_by_chunk: HashMap::new(),
201 entity_by_id: IntMap::default(),
202 registries: RegistryHolder::default(),
203 }
204 }
205}