GeezerVison is showing github.com — Handle breaking of large chests · BuggStream/feather@885922d
File treeExpand file treeCollapse file tree Open diff view settings player/src/packet_handlers
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: server/block/src/chest.rs +42-6Lines changed: 42 additions & 6 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -98,6 +98,38 @@ pub fn on_chest_create_try_connect(event: &BlockUpdateEvent, game: &mut Game, wo | 98 | 98 | try_connect_chests(game, world, event.pos); | 99 | 99 | } | 100 | 100 |
| | 101 | +/// When a chest is broken and it is connected with another chest, | | 102 | +/// set the other chest as ChestKind::Single. | | 103 | +#[fecs::event_handler] | | 104 | +pub fn on_chest_break_try_disconnect(event: &BlockUpdateEvent, game: &mut Game, world: &mut World) { | | 105 | + if event.old.kind() != BlockKind::Chest || event.new.kind() == BlockKind::Chest { | | 106 | + return; | | 107 | + } | | 108 | + | | 109 | + let kind = event.old.chest_kind().expect("chest has kind"); | | 110 | + | | 111 | + if let Some((left, right)) = connected_chest(event.pos, event.old) { | | 112 | + // Unintuitively, ChestKind::Left means that the chest it is connected to is | | 113 | + // to the left, so it is actually the _right_ hand chest. | | 114 | + // This is a Mojang naming issue. | | 115 | + | | 116 | + // Find which chest is not at event.pos. | | 117 | + let to_update = match kind { | | 118 | + ChestKind::Left => left, | | 119 | + ChestKind::Right => right, | | 120 | + ChestKind::Single => unreachable!(), | | 121 | + }; | | 122 | + debug_assert!(to_update != event.pos); | | 123 | + | | 124 | + let old_block = game.block_at(to_update); | | 125 | + if let Some(old_block) = old_block { | | 126 | + let new_block = old_block.with_chest_kind(ChestKind::Single); | | 127 | + | | 128 | + game.set_block_at(world, to_update, new_block, BlockUpdateCause::Unknown); | | 129 | + } | | 130 | + } | | 131 | +} | | 132 | + | 101 | 133 | fn create_spawn_packet(accessor: &EntityRef) -> Box<dyn Packet> { | 102 | 134 | Box::new(viewers_packet(accessor)) | 103 | 135 | } | @@ -208,9 +240,10 @@ fn load_inventory(slots: &[InventorySlot]) -> Inventory { | 208 | 240 | /// If the block at the given position is a chest, and it is connected | 209 | 241 | /// to another chest to form a large chest, returns a tuple (left, right) | 210 | 242 | // where `left` is the left chest and `right` is the right chest position. | 211 | | -pub fn connected_chest(game: &Game, pos: BlockPosition) -> Option<(BlockPosition, BlockPosition)> { | 212 | | - let block = game.block_at(pos).unwrap_or_default(); | 213 | | - | | 243 | +pub fn connected_chest( | | 244 | + pos: BlockPosition, | | 245 | + block: BlockId, | | 246 | +) -> Option<(BlockPosition, BlockPosition)> { | 214 | 247 | if block.kind() != BlockKind::Chest { | 215 | 248 | return None; | 216 | 249 | } | @@ -341,7 +374,7 @@ impl InteractionHandler for ChestInteraction { | 341 | 374 | } | 342 | 375 |
| 343 | 376 | fn opened_chests(game: &Game, pos: BlockPosition) -> ArrayVec<[Option<Entity>; 2]> { | 344 | | - if let Some((left, right)) = connected_chest(game, pos) { | | 377 | + if let Some((left, right)) = connected_chest(pos, game.block_at(pos).unwrap_or_default()) { | 345 | 378 | ArrayVec::from([ | 346 | 379 | game.block_entities.get(&left).copied(), | 347 | 380 | game.block_entities.get(&right).copied(), | @@ -475,7 +508,7 @@ mod tests { | 475 | 508 | )); | 476 | 509 |
| 477 | 510 | assert_eq!( | 478 | | - connected_chest(&test.game, pos_left), | | 511 | + connected_chest(pos_left, block_left), | 479 | 512 | Some((pos_left, pos_right)) | 480 | 513 | ); | 481 | 514 | } | @@ -492,7 +525,10 @@ mod tests { | 492 | 525 | ); | 493 | 526 |
| 494 | 527 | assert_eq!( | 495 | | - connected_chest(&test.game, BlockPosition::new(0, 0, 0)), | | 528 | + connected_chest( | | 529 | + BlockPosition::new(0, 0, 0), | | 530 | + BlockId::chest().with_chest_kind(ChestKind::Single) | | 531 | + ), | 496 | 532 | None | 497 | 533 | ); | 498 | 534 | } | |
Collapse file Copy file name to clipboardExpand all lines: server/block/src/lib.rs +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -4,8 +4,8 @@ pub mod chest; | 4 | 4 | mod init; | 5 | 5 |
| 6 | 6 | pub use chest::{ | 7 | | - on_chest_break_drop_contents, on_chest_close_decrement_viewers, on_chest_create_try_connect, | 8 | | - on_chest_open_increment_viewers, | | 7 | + on_chest_break_drop_contents, on_chest_break_try_disconnect, on_chest_close_decrement_viewers, | | 8 | + on_chest_create_try_connect, on_chest_open_increment_viewers, | 9 | 9 | }; | 10 | 10 | use feather_core::{ | 11 | 11 | anvil::block_entity::BlockEntityBase, | |
Collapse file Copy file name to clipboardExpand all lines: server/player/src/packet_handlers/inventory.rs -7Lines changed: 0 additions & 7 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -324,9 +324,7 @@ fn handle_single_click( | 324 | 324 | packet: ClickWindow, | 325 | 325 | button: MouseButton, | 326 | 326 | ) -> anyhow::Result<()> { | 327 | | - log::debug!("----begin handle_single_click for slot {}----", packet.slot); | 328 | 327 | if let Some(picked) = world.try_get::<PickedItem>(player).map(|i| *i) { | 329 | | - log::debug!("item is held; putting down or swapping"); | 330 | 328 | // Put down the item on the clicked slot. Based on the mouse button: | 331 | 329 | // * left => whole stack | 332 | 330 | // * right => single item | @@ -346,15 +344,13 @@ fn handle_single_click( | 346 | 344 | Some(item) | 347 | 345 | } | 348 | 346 | }) { | 349 | | - log::debug!("swapping"); | 350 | 347 | // Different items - swap | 351 | 348 | accessor.set_item_at(packet.slot as usize, picked.0)?; | 352 | 349 | drop(accessor); | 353 | 350 | drop(window); | 354 | 351 | world.get_mut::<PickedItem>(player).0 = current_item; | 355 | 352 | } else { | 356 | 353 | // Place item on slot | 357 | | - log::debug!("placing item"); | 358 | 354 | let count = match button { | 359 | 355 | MouseButton::Left => picked.0.amount, | 360 | 356 | MouseButton::Right => 1, | @@ -375,7 +371,6 @@ fn handle_single_click( | 375 | 371 | } | 376 | 372 | } | 377 | 373 | } else { | 378 | | - log::debug!("no item is held; picking up"); | 379 | 374 | let window = world.get::<Window>(player); | 380 | 375 | let accessor = window.accessor(world)?; | 381 | 376 |
| @@ -414,8 +409,6 @@ fn handle_single_click( | 414 | 409 | }, | 415 | 410 | ); | 416 | 411 |
| 417 | | - log::debug!("----end handle_single_click----"); | 418 | | - | 419 | 412 | Ok(()) | 420 | 413 | } | 421 | 414 |
| |
Collapse file Copy file name to clipboardExpand all lines: server/src/event_handlers.rs +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -28,6 +28,7 @@ pub fn build_event_handlers() -> EventHandlers { | 28 | 28 | on_chest_break_drop_contents, | 29 | 29 | on_block_update_create_block_entity, | 30 | 30 | on_chest_create_try_connect, | | 31 | + on_chest_break_try_disconnect, | 31 | 32 |
| 32 | 33 | on_entity_despawn_remove_chunk_holder, | 33 | 34 | on_entity_despawn_update_chunk_entities, | |
|