diff options
| author | mat <git@matdoes.dev> | 2023-05-26 15:18:04 -0500 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2023-05-26 15:18:04 -0500 |
| commit | 6188230009b49f96b755ade32a28b932e7810196 (patch) | |
| tree | f7b6bc8e25dfda27f3162f9e6bd53721fb3a86cc /azalea-client/src/interact.rs | |
| parent | 9bdace4aab064257dccb39fab4d47fde6dd9a062 (diff) | |
| download | azalea-drasl-6188230009b49f96b755ade32a28b932e7810196.tar.xz | |
add stuff related to chat signing
and also some stuff related to digging because i forgot to do a different branch lol
Diffstat (limited to 'azalea-client/src/interact.rs')
| -rw-r--r-- | azalea-client/src/interact.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/azalea-client/src/interact.rs b/azalea-client/src/interact.rs index fa05aa49..afb55bbf 100644 --- a/azalea-client/src/interact.rs +++ b/azalea-client/src/interact.rs @@ -1,4 +1,7 @@ +use azalea_block::BlockState; use azalea_core::{BlockHitResult, BlockPos, Direction, GameMode, Vec3}; +use azalea_inventory::{ItemSlot, ItemSlotData}; +use azalea_nbt::NbtList; use azalea_physics::clip::{BlockShapeType, ClipContext, FluidPickType}; use azalea_protocol::packets::game::{ serverbound_interact_packet::InteractionHand, @@ -20,6 +23,8 @@ use derive_more::{Deref, DerefMut}; use log::warn; use crate::{ + client::PlayerAbilities, + inventory::InventoryComponent, local_player::{handle_send_packet_event, LocalGameMode}, Client, LocalPlayer, }; @@ -193,3 +198,68 @@ pub fn pick( }, ) } + +/// Whether we can't interact with the block, based on your gamemode. If +/// this is false, then we can interact with the block. +/// +/// Passing the inventory, block position, and instance is necessary for the +/// adventure mode check. +pub fn check_is_interaction_restricted( + instance: &Instance, + block_pos: &BlockPos, + game_mode: &GameMode, + inventory: &InventoryComponent, +) -> bool { + match game_mode { + GameMode::Adventure => { + // vanilla checks for abilities.mayBuild here but servers have no + // way of modifying that + + let held_item = inventory.held_item(); + if let ItemSlot::Present(item) = &held_item { + let block = instance.chunks.get_block_state(block_pos); + let Some(block) = block else { + // block isn't loaded so just say that it is restricted + return true; + }; + check_block_can_be_broken_by_item_in_adventure_mode(item, &block) + } else { + true + } + } + GameMode::Spectator => true, + _ => false, + } +} + +/// Check if the item has the `CanDestroy` tag for the block. +pub fn check_block_can_be_broken_by_item_in_adventure_mode( + item: &ItemSlotData, + block: &BlockState, +) -> bool { + // minecraft caches the last checked block but that's kind of an unnecessary + // optimization and makes the code too complicated + + let Some(can_destroy) = item + .nbt + .as_compound() + .and_then(|nbt| nbt.get("tag").and_then(|nbt| nbt.as_compound())) + .and_then(|nbt| nbt.get("CanDestroy").and_then(|nbt| nbt.as_list())) else { + // no CanDestroy tag + return false; + }; + + let NbtList::String(can_destroy) = can_destroy else { + // CanDestroy tag must be a list of strings + return false; + }; + + return false; + + // for block_predicate in can_destroy { + // // TODO + // // defined in BlockPredicateArgument.java + // } + + // true +} |
