veloren_common/states/
wielding.rs

1use super::utils::*;
2use crate::{
3    comp::{
4        CharacterState, InventoryAction, StateUpdate,
5        character_state::OutputEvents,
6        slot::{EquipSlot, Slot},
7    },
8    states::{
9        behavior::{CharacterBehavior, JoinData},
10        idle,
11    },
12};
13use serde::{Deserialize, Serialize};
14
15#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
16pub struct Data {
17    pub is_sneaking: bool,
18}
19
20impl CharacterBehavior for Data {
21    fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
22        let mut update = StateUpdate::from(data);
23
24        handle_orientation(data, &mut update, 1.0, None);
25        handle_move(data, &mut update, if self.is_sneaking { 0.4 } else { 1.0 });
26        handle_climb(data, &mut update);
27        handle_wallrun(data, &mut update);
28        attempt_input(data, output_events, &mut update);
29        handle_jump(data, output_events, &mut update, 1.0);
30
31        if self.is_sneaking
32            && (data.physics.on_ground.is_none() || data.physics.in_liquid().is_some())
33        {
34            update.character = CharacterState::Wielding(Data { is_sneaking: false });
35        }
36
37        update
38    }
39
40    fn swap_equipped_weapons(
41        &self,
42        data: &JoinData,
43        output_events: &mut OutputEvents,
44    ) -> StateUpdate {
45        let mut update = StateUpdate::from(data);
46        attempt_swap_equipped_weapons(data, &mut update, output_events);
47        update
48    }
49
50    fn manipulate_loadout(
51        &self,
52        data: &JoinData,
53        output_events: &mut OutputEvents,
54        inv_action: InventoryAction,
55    ) -> StateUpdate {
56        let mut update = StateUpdate::from(data);
57        let reset_to_idle = match inv_action {
58            InventoryAction::Drop(slot)
59            | InventoryAction::Swap(slot, _)
60            | InventoryAction::Swap(_, Slot::Equip(slot))
61                if matches!(slot, EquipSlot::ActiveMainhand | EquipSlot::ActiveOffhand) =>
62            {
63                true
64            },
65            InventoryAction::Use(_) => true,
66            _ => false,
67        };
68        if reset_to_idle {
69            update.character = CharacterState::Idle(idle::Data {
70                is_sneaking: data.character.is_stealthy(),
71                time_entered: *data.time,
72                footwear: None,
73            });
74        }
75        handle_manipulate_loadout(data, output_events, &mut update, inv_action);
76        update
77    }
78
79    fn glide_wield(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
80        let mut update = StateUpdate::from(data);
81        attempt_glide_wield(data, &mut update, output_events);
82        update
83    }
84
85    fn unwield(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
86        let mut update = StateUpdate::from(data);
87        update.character = CharacterState::Idle(idle::Data {
88            is_sneaking: self.is_sneaking,
89            time_entered: *data.time,
90            footwear: None,
91        });
92        update
93    }
94
95    fn sit(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
96        let mut update = StateUpdate::from(data);
97        attempt_sit(data, &mut update);
98        update
99    }
100
101    fn crawl(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
102        let mut update = StateUpdate::from(data);
103        attempt_crawl(data, &mut update);
104        update
105    }
106
107    fn dance(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
108        let mut update = StateUpdate::from(data);
109        attempt_dance(data, &mut update);
110        update
111    }
112
113    fn sneak(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
114        let mut update = StateUpdate::from(data);
115        if data.physics.on_ground.is_some() && data.body.is_humanoid() {
116            update.character = CharacterState::Wielding(Data { is_sneaking: true });
117        }
118        update
119    }
120
121    fn stand(&self, data: &JoinData, _: &mut OutputEvents) -> StateUpdate {
122        let mut update = StateUpdate::from(data);
123        update.character = CharacterState::Wielding(Data { is_sneaking: false });
124        update
125    }
126}