mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-08 06:48:22 -10:00
Send decorated pot sherds to LAN guests
Decorated pots showed no sherds for LAN guests. A pot is not a block entity here, so the hub and the chunk encoder read the saved tag for it and send the sherds, loot table and item (DecoratedPotBlockEntity.getUpdateTag, saveCustomOnly). Inserting into a pot marks it for update, and a client stores a pot update with the chunk.
This commit is contained in:
1 parent
2ad7b68710
commit
1deb3bd36c
4 files changed
+44
-3
No files matched your search
@@ -131,6 +131,8 @@ impl Game<'_> {
|
||||
map.insert("item".into(), save::item_to_nbt(item));
|
||||
}
|
||||
spill::put_saved_entity(&mut self.world, pos, tag);
|
||||
// The sherds and item go to the guests (BlockEntityData).
|
||||
self.mark_block_entity_updated((pos[0], pos[1], pos[2]));
|
||||
self.consume_held();
|
||||
self.audio.play(
|
||||
"minecraft:block.decorated_pot.insert",
|
||||
|
||||
@@ -1148,6 +1148,23 @@ impl Game<'_> {
|
||||
else {
|
||||
return;
|
||||
};
|
||||
// A decorated pot is no block entity here: its tag is kept with the chunk.
|
||||
if name == "minecraft:decorated_pot" {
|
||||
if let Tag::Compound(fields) = tag
|
||||
&& !fields.is_empty()
|
||||
{
|
||||
let mut full = fields.clone();
|
||||
full.insert("id".into(), Tag::String(name.into()));
|
||||
for (k, v) in ["x", "y", "z"].into_iter().zip(pos) {
|
||||
full.insert(k.into(), Tag::Int(v));
|
||||
}
|
||||
super::spill::put_saved_entity(&mut self.world, pos, Tag::Compound(full));
|
||||
// The section is drawn again with the pot's sherds.
|
||||
let state = self.world.block(pos[0], pos[1], pos[2]);
|
||||
let _ = self.world.set(pos[0], pos[1], pos[2], state);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let Some(entity) = self.world.block_entities.get(&key) else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -824,6 +824,7 @@ impl ChunkEncoder {
|
||||
tag: block_entities
|
||||
.get(&pos)
|
||||
.and_then(entity_tag)
|
||||
.or_else(|| pot_tag(chunk, pos))
|
||||
.unwrap_or(Tag::End),
|
||||
});
|
||||
}
|
||||
@@ -984,6 +985,22 @@ pub fn entity_tag(entity: &BlockEntity) -> Option<Tag> {
|
||||
}
|
||||
}
|
||||
|
||||
/// The update tag of the decorated pot at `pos` (DecoratedPotBlockEntity.getUpdateTag,
|
||||
/// saveCustomOnly). A pot is not a block entity here: its tag is the chunk's saved one.
|
||||
pub fn pot_tag(chunk: &Chunk, pos: (i32, i32, i32)) -> Option<Tag> {
|
||||
let at = chunk.saved.as_ref()?.block_entities.iter().find(|t| {
|
||||
t.get("id") == Some(&Tag::String("minecraft:decorated_pot".into()))
|
||||
&& t.get("x") == Some(&Tag::Int(pos.0))
|
||||
&& t.get("y") == Some(&Tag::Int(pos.1))
|
||||
&& t.get("z") == Some(&Tag::Int(pos.2))
|
||||
})?;
|
||||
let entries: Vec<_> = ["sherds", "LootTable", "LootTableSeed", "item"]
|
||||
.into_iter()
|
||||
.filter_map(|k| Some((k, at.get(k)?.clone())))
|
||||
.collect();
|
||||
(!entries.is_empty()).then(|| Tag::compound(entries))
|
||||
}
|
||||
|
||||
/// Light sections run from one below the world to one above it. A layer
|
||||
/// exists where vanilla's light storage keeps one: within one section of a
|
||||
/// non-air section of this column or a neighbouring one (`around`, bit i for
|
||||
|
||||
@@ -1566,10 +1566,15 @@ impl Hub {
|
||||
}
|
||||
// Block entities with data the client shows.
|
||||
for &(x, y, z) in &positions {
|
||||
let Some(entity) = world.block_entities.get(&(x, y, z)) else {
|
||||
continue;
|
||||
// A decorated pot is no block entity: its tag is the chunk's saved one.
|
||||
let tag = match world.block_entities.get(&(x, y, z)) {
|
||||
Some(entity) => super::chunks::entity_tag(entity),
|
||||
None => world
|
||||
.chunks
|
||||
.get(&(x >> 4, z >> 4))
|
||||
.and_then(|c| super::chunks::pot_tag(c, (x, y, z))),
|
||||
};
|
||||
let Some(tag) = super::chunks::entity_tag(entity) else {
|
||||
let Some(tag) = tag else {
|
||||
continue;
|
||||
};
|
||||
let state = world.block(x, y, z).0;
|
||||
|
||||
Reference in new issue
Block a user