1use std::{
2 collections::{HashMap, HashSet},
3 fmt::{self, Debug, Display},
4 hash::{Hash, Hasher},
5 io::{self, Cursor},
6};
7
8use azalea_block::{BlockState, fluid_state::FluidState};
9use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
10use azalea_core::{
11 position::{BlockPos, ChunkPos},
12 registry_holder::RegistryHolder,
13};
14use azalea_registry::Biome;
15use bevy_ecs::{component::Component, entity::Entity};
16use derive_more::{Deref, DerefMut};
17use nohash_hasher::IntMap;
18#[cfg(feature = "serde")]
19use serde::{Deserialize, Serialize};
20
21use crate::{ChunkStorage, PartialChunkStorage};
22
23pub struct PartialInstance {
32 pub chunks: PartialChunkStorage,
33 pub entity_infos: PartialEntityInfos,
36}
37
38impl PartialInstance {
39 pub fn new(chunk_radius: u32, owner_entity: Option<Entity>) -> Self {
40 PartialInstance {
41 chunks: PartialChunkStorage::new(chunk_radius),
42 entity_infos: PartialEntityInfos::new(owner_entity),
43 }
44 }
45
46 pub fn reset(&mut self) {
49 self.chunks = PartialChunkStorage::new(self.chunks.chunk_radius);
50 }
51}
52
53#[derive(Component, Copy, Clone, Debug, Default, PartialEq, Eq, Deref, DerefMut)]
70#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
71pub struct MinecraftEntityId(pub i32);
72
73impl Hash for MinecraftEntityId {
74 fn hash<H: Hasher>(&self, hasher: &mut H) {
75 hasher.write_i32(self.0);
76 }
77}
78impl nohash_hasher::IsEnabled for MinecraftEntityId {}
79
80impl AzaleaRead for MinecraftEntityId {
83 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
84 i32::azalea_read(buf).map(MinecraftEntityId)
85 }
86}
87impl AzaleaWrite for MinecraftEntityId {
88 fn azalea_write(&self, buf: &mut impl io::Write) -> io::Result<()> {
89 i32::azalea_write(&self.0, buf)
90 }
91}
92impl AzaleaReadVar for MinecraftEntityId {
93 fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
94 i32::azalea_read_var(buf).map(MinecraftEntityId)
95 }
96}
97impl AzaleaWriteVar for MinecraftEntityId {
98 fn azalea_write_var(&self, buf: &mut impl io::Write) -> io::Result<()> {
99 i32::azalea_write_var(&self.0, buf)
100 }
101}
102impl Display for MinecraftEntityId {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 write!(f, "eid({})", self.0)
105 }
106}
107impl From<i32> for MinecraftEntityId {
108 fn from(id: i32) -> Self {
109 Self(id)
110 }
111}
112impl From<u32> for MinecraftEntityId {
113 fn from(id: u32) -> Self {
114 Self(id as i32)
115 }
116}
117
118#[derive(Debug, Default)]
121pub struct PartialEntityInfos {
122 pub owner_entity: Option<Entity>,
127 pub updates_received: IntMap<MinecraftEntityId, u32>,
133 }
136
137impl PartialEntityInfos {
138 pub fn new(owner_entity: Option<Entity>) -> Self {
139 Self {
140 owner_entity,
141 updates_received: IntMap::default(),
142 }
143 }
144}
145
146#[derive(Default, Debug)]
154pub struct Instance {
155 pub chunks: ChunkStorage,
156
157 pub entities_by_chunk: HashMap<ChunkPos, HashSet<Entity>>,
159
160 pub entity_by_id: IntMap<MinecraftEntityId, Entity>,
167
168 pub registries: RegistryHolder,
169}
170
171impl Instance {
172 pub fn get_block_state(&self, pos: BlockPos) -> Option<BlockState> {
173 self.chunks.get_block_state(pos)
174 }
175
176 pub fn get_fluid_state(&self, pos: BlockPos) -> Option<FluidState> {
177 self.chunks.get_block_state(pos).map(FluidState::from)
178 }
179
180 pub fn get_biome(&self, pos: BlockPos) -> Option<Biome> {
189 self.chunks.get_biome(pos)
190 }
191
192 pub fn set_block_state(&self, pos: BlockPos, state: BlockState) -> Option<BlockState> {
193 self.chunks.set_block_state(pos, state)
194 }
195}
196
197impl Debug for PartialInstance {
198 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199 f.debug_struct("PartialInstance")
200 .field("chunks", &self.chunks)
201 .field("entity_infos", &self.entity_infos)
202 .finish()
203 }
204}
205
206impl Default for PartialInstance {
207 fn default() -> Self {
210 let chunk_storage = PartialChunkStorage::default();
211 let entity_storage = PartialEntityInfos::default();
212 Self {
213 chunks: chunk_storage,
214 entity_infos: entity_storage,
215 }
216 }
217}
218
219impl From<ChunkStorage> for Instance {
220 fn from(chunks: ChunkStorage) -> Self {
223 Self {
224 chunks,
225 entities_by_chunk: HashMap::new(),
226 entity_by_id: IntMap::default(),
227 registries: RegistryHolder::default(),
228 }
229 }
230}