Skip to main content

steel_core/behavior/
item_utils.rs

1//! Helpers shared by item behavior implementations.
2
3use crate::player::player_inventory::Prediction;
4use steel_registry::item_stack::ItemStack;
5use steel_registry::items::item::BlockHitResult;
6
7use crate::behavior::UseItemContext;
8use crate::inventory::lock::ContainerId;
9use crate::player::Player;
10use crate::player::player_inventory::PlayerInventory;
11use crate::world::{ClipBlockShape, ClipFluid, World};
12
13#[must_use]
14pub(crate) fn get_player_pov_hit_result(
15    world: &World,
16    player: &Player,
17    fluid: ClipFluid,
18) -> BlockHitResult {
19    let (from, to) = player.get_ray_endpoints();
20    let hit = world.clip(from, to, ClipBlockShape::Outline, fluid);
21    BlockHitResult {
22        location: hit.location,
23        direction: hit.direction,
24        block_pos: hit.block_pos,
25        miss: hit.miss,
26        inside: hit.inside,
27        world_border_hit: hit.world_border_hit,
28    }
29}
30
31pub(crate) fn create_filled_result(
32    context: &UseItemContext,
33    result_stack: ItemStack,
34    limit_creative_stack_size: bool,
35) {
36    let player = context.player;
37    let overflow = context.inv.with_guard(|guard| {
38        let inv_id = ContainerId::from_arc(&player.inventory);
39        let Some(inv) = guard.get_typed_mut::<PlayerInventory>(inv_id) else {
40            return result_stack;
41        };
42
43        inv.apply_filled_result(
44            context.hand,
45            result_stack,
46            player.has_infinite_materials(),
47            limit_creative_stack_size,
48        )
49    });
50
51    if !overflow.is_empty() {
52        let _ = player.drop_item(overflow, false, Prediction::Predicted);
53    }
54}