Skip to main content

steel_core/behavior/items/
snowball.rs

1//! Snowball item behavior (`SnowballItem`).
2//!
3//! Throwing a snowball spawns a [`SnowballEntity`] from the player's eye, shot
4//! along their look direction, and consumes one snowball unless the player
5//! has infinite materials. Mirrors vanilla `SnowballItem.use`.
6
7use std::sync::Arc;
8
9use steel_macros::item_behavior;
10use steel_protocol::packets::game::SoundSource;
11use steel_registry::{sound_events, vanilla_entities};
12
13use super::throw_projectile::{ThrowParams, throw_item_projectile};
14use crate::behavior::context::{InteractionResult, UseItemContext};
15use crate::behavior::item::ItemBehavior;
16use crate::entity::entities::SnowballEntity;
17use crate::entity::next_entity_id;
18
19/// Sound, shoot power and spread used when throwing a snowball.
20const THROW: ThrowParams = ThrowParams {
21    sound: &sound_events::ENTITY_SNOWBALL_THROW,
22    sound_source: SoundSource::Neutral,
23    sound_volume: 0.5,
24    y_offset: 0.0,
25    power: 1.5,
26    uncertainty: 1.0,
27};
28
29/// Behavior for the snowball item.
30#[item_behavior(class = "SnowballItem")]
31pub struct SnowballItem;
32
33impl ItemBehavior for SnowballItem {
34    fn use_item(&self, context: &mut UseItemContext) -> InteractionResult {
35        let world = context.world;
36        throw_item_projectile(context, &THROW, |spawn_pos| {
37            SnowballEntity::new(
38                &vanilla_entities::SNOWBALL,
39                next_entity_id(),
40                spawn_pos,
41                Arc::downgrade(world),
42            )
43        });
44        InteractionResult::Success
45    }
46}