veloren_voxygen_anim/biped_small/
summon.rs

1use super::{
2    super::{Animation, vek::*},
3    BipedSmallSkeleton, SkeletonAttr,
4};
5use common::{comp::item::ToolKind, states::utils::StageSection};
6use std::f32::consts::PI;
7
8pub struct SummonAnimation;
9
10type SummonAnimationDependency<'a> = (
11    Option<&'a str>,
12    Option<ToolKind>,
13    Vec3<f32>,
14    Vec3<f32>,
15    Vec3<f32>,
16    f32,
17    Vec3<f32>,
18    f32,
19    Option<StageSection>,
20    f32,
21);
22
23impl Animation for SummonAnimation {
24    type Dependency<'a> = SummonAnimationDependency<'a>;
25    type Skeleton = BipedSmallSkeleton;
26
27    #[cfg(feature = "use-dyn-lib")]
28    const UPDATE_FN: &'static [u8] = b"biped_small_summon\0";
29
30    #[cfg_attr(feature = "be-dyn-lib", unsafe(export_name = "biped_small_summon"))]
31
32    fn update_skeleton_inner(
33        skeleton: &Self::Skeleton,
34        (
35            ability_id,
36            active_tool_kind,
37            _velocity,
38            _orientation,
39            _last_ori,
40            global_time,
41            _avg_vel,
42            _acc_vel,
43            stage_section,
44            timer,
45        ): Self::Dependency<'_>,
46        anim_time: f32,
47        _rate: &mut f32,
48        s_a: &SkeletonAttr,
49    ) -> Self::Skeleton {
50        let mut next = (*skeleton).clone();
51
52        let anim_time = anim_time.min(1.0);
53        let (move1base, twitch, twitch2, move2base, move3) = match stage_section {
54            Some(StageSection::Buildup) => {
55                (anim_time.sqrt(), (anim_time * 5.0).sin(), 0.0, 0.0, 0.0)
56            },
57            Some(StageSection::Action) => {
58                (1.0, 1.0, (anim_time * 10.0).sin(), anim_time.powi(4), 0.0)
59            },
60            Some(StageSection::Recover) => (1.0, 1.0, 1.0, 1.0, anim_time),
61            _ => (0.0, 0.0, 0.0, 0.0, 0.0),
62        };
63        let pullback = 1.0 - move3;
64        let twitch = twitch * pullback;
65        let twitch2 = twitch2 * pullback;
66        let subtract = global_time - timer;
67        let check = subtract - subtract.trunc();
68        let mirror = (check - 0.5).signum();
69        let move1 = move1base * pullback * mirror;
70        let move2 = move2base * pullback * mirror;
71        let move1abs = move1base * pullback;
72        let move2abs = move2base * pullback;
73        next.hand_l.position = Vec3::new(s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
74        next.hand_r.position = Vec3::new(-s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
75        next.main.position = Vec3::new(0.0, 0.0, 0.0);
76        next.main.orientation = Quaternion::rotation_x(0.0);
77        next.hand_l.orientation = Quaternion::rotation_x(0.0);
78        next.hand_r.orientation = Quaternion::rotation_x(0.0);
79        match active_tool_kind {
80            Some(ToolKind::Staff) => match ability_id {
81                Some("common.abilities.custom.dwarves.flamekeeper.summon_lavathrower") => {
82                    next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 3.0, 3.0);
83                    next.control_r.position = Vec3::new(
84                        12.0 + s_a.grip.0 * 2.0,
85                        -4.0 + move1abs * -20.0,
86                        3.0 + twitch * 2.0 + twitch2 * 2.0,
87                    );
88
89                    next.control.position = Vec3::new(
90                        -5.0 + move1abs * -5.0,
91                        -1.0 + s_a.grip.2 + move1abs * -8.0,
92                        -2.0 + -s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0 + twitch2 * -2.0,
93                    );
94                    next.chest.position =
95                        Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + twitch2 + move2abs * 2.0);
96                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0)
97                        * Quaternion::rotation_y(-0.3)
98                        * Quaternion::rotation_z(-0.3);
99                    next.control_r.orientation = Quaternion::rotation_x(
100                        PI / 2.0 + s_a.grip.0 * 0.2 + twitch * 0.2 + twitch2 * 0.2,
101                    ) * Quaternion::rotation_y(
102                        -0.4 + s_a.grip.0 * 0.2 + move1abs * -2.0,
103                    ) * Quaternion::rotation_z(move1abs * 0.5);
104
105                    next.control.orientation = Quaternion::rotation_x(-0.3)
106                        * Quaternion::rotation_y(0.0)
107                        * Quaternion::rotation_z(0.5 + move1abs * 1.0);
108                    next.chest.orientation =
109                        Quaternion::rotation_x(0.0) * Quaternion::rotation_z(0.0);
110                    next.head.orientation =
111                        Quaternion::rotation_z(twitch * 0.2 + twitch2 * 0.4 + move2abs * -0.5)
112                            * Quaternion::rotation_x(move2abs * 0.7);
113                },
114                Some("common.abilities.custom.ashen_warrior.staff.flame_wall") => {
115                    let slow = (global_time * 4.0).sin();
116                    let (move1base, move2base, move3base) = match stage_section {
117                        Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
118                        Some(StageSection::Action) => (1.0, anim_time, 0.0),
119                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
120                        _ => (0.0, 0.0, 0.0),
121                    };
122
123                    let pullback = 1.0 - move3base;
124                    let move1 = move1base * pullback;
125
126                    next.control.position +=
127                        Vec3::new(-8.0, 8.0, 10.0) * move1 + Vec3::new(0.5, 0.5, 2.0) * slow;
128                    next.control.orientation.rotate_z(0.15 * slow);
129                    next.control.orientation.rotate_x(-PI / 10.0 * move1);
130                    next.control_l.position += Vec3::new(7.0, -2.0, 0.0) * move1;
131                    next.control_l.orientation.rotate_x(PI / 1.3 * move1);
132                    next.control_l.orientation.rotate_z(-PI / 4.0 * move1);
133                    next.control_r.position += Vec3::new(4.0, -2.0, 0.0) * move1;
134                    next.control_r.orientation.rotate_x(PI / 1.3 * move1);
135                    next.control_r.orientation.rotate_z(PI / 2.0 * move1);
136
137                    next.chest.orientation.rotate_z(2.0 * PI * move2base);
138                    next.foot_l.position += Vec3::new(
139                        (2.0 * PI * move2base + PI).cos() + 1.0,
140                        (2.0 * PI * move2base + PI).sin(),
141                        0.0,
142                    ) * 3.0;
143                    next.foot_l.orientation.rotate_z(2.0 * PI * move2base);
144                    next.foot_r.position += Vec3::new(
145                        (2.0 * PI * move2base).cos() - 1.0,
146                        (2.0 * PI * move2base).sin(),
147                        0.0,
148                    ) * 3.0;
149                    next.foot_r.orientation.rotate_z(2.0 * PI * move2base);
150                },
151                Some("common.abilities.custom.ashen_warrior.staff.summon_crux") => {
152                    let slow = (global_time * 4.0).sin();
153                    let (move1base, _, move3base) = match stage_section {
154                        Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
155                        Some(StageSection::Action) => (1.0, anim_time, 0.0),
156                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
157                        _ => (0.0, 0.0, 0.0),
158                    };
159
160                    let pullback = 1.0 - move3base;
161                    let move1 = move1base * pullback;
162
163                    next.main.position = Vec3::new(-10.0, 5.0, 0.0);
164                    next.main.orientation = Quaternion::rotation_x(0.0);
165                    next.hand_l.position = Vec3::new(s_a.grip.0 * 5.0, 0.0, 2.0);
166                    next.hand_l.orientation = Quaternion::rotation_x(PI / 2.0);
167                    next.hand_r.position = Vec3::new(-s_a.grip.0 * 5.0, 0.0, 2.0);
168                    next.hand_r.orientation = Quaternion::rotation_x(PI / 2.0);
169
170                    next.head.position += Vec3::new(0.0, -4.0, 0.0) * move1;
171                    next.head.orientation.rotate_x(PI / 10.0 * move1);
172                    next.chest.orientation.rotate_x(PI / 10.0 * move1);
173                    next.hand_l.orientation.rotate_x(PI / 10.0 * move1);
174                    next.hand_l.orientation.rotate_y(PI / 10.0 * move1);
175                    next.hand_r.orientation.rotate_x(PI / 10.0 * move1);
176                    next.hand_r.orientation.rotate_y(-PI / 10.0 * move1);
177                    next.main.position += Vec3::new(0.0, 0.0, 2.0) * move1;
178                    next.main.orientation.rotate_y(PI / 10.0 * move1);
179                    next.control.position +=
180                        Vec3::new(0.0, 4.0, 10.0) * move1 + Vec3::new(0.5, 0.5, 2.0) * slow;
181                },
182                _ => {
183                    next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0);
184                    next.control_r.position = Vec3::new(
185                        7.0 + s_a.grip.0 * 2.0,
186                        -4.0 + move1abs * -14.0,
187                        3.0 + twitch * 2.0 + twitch2 * 2.0,
188                    );
189
190                    next.control.position = Vec3::new(
191                        -5.0 + move1abs * -5.0,
192                        -1.0 + s_a.grip.2 + move1abs * -8.0,
193                        -2.0 + -s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0 + twitch2 * -2.0,
194                    );
195                    next.chest.position =
196                        Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + twitch2 + move2abs * 3.0);
197                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0)
198                        * Quaternion::rotation_y(-0.3)
199                        * Quaternion::rotation_z(-0.3);
200                    next.control_r.orientation = Quaternion::rotation_x(
201                        PI / 2.0 + s_a.grip.0 * 0.2 + twitch * 0.2 + twitch2 * 0.2,
202                    ) * Quaternion::rotation_y(
203                        -0.4 + s_a.grip.0 * 0.2 + move1abs * -2.0,
204                    ) * Quaternion::rotation_z(move1abs * 0.5);
205
206                    next.control.orientation = Quaternion::rotation_x(-0.3)
207                        * Quaternion::rotation_y(0.0)
208                        * Quaternion::rotation_z(0.5 + move1abs * 1.0);
209                    next.chest.orientation =
210                        Quaternion::rotation_x(0.0) * Quaternion::rotation_z(0.0);
211                    next.head.orientation =
212                        Quaternion::rotation_z(twitch * 0.2 + twitch2 * 0.4 + move2abs * -0.5)
213                            * Quaternion::rotation_x(move2abs * 0.7);
214                },
215            },
216            Some(ToolKind::Sword) => {
217                next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 3.0, 3.0);
218                next.control_r.position =
219                    Vec3::new(12.0 + s_a.grip.0 * 2.0, -4.0 + move1abs * -14.0, 3.0);
220
221                next.control.position = Vec3::new(
222                    -5.0 + move1abs * -5.0,
223                    -1.0 + s_a.grip.2 + move1abs * -8.0,
224                    s_a.grip.2 / 2.0,
225                );
226                next.chest.position =
227                    Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + twitch2 + move2abs * 2.0);
228                next.control_l.orientation = Quaternion::rotation_x(PI / 2.0)
229                    * Quaternion::rotation_y(-0.3)
230                    * Quaternion::rotation_z(-0.3);
231                next.control_r.orientation = Quaternion::rotation_x(
232                    PI / 2.0 + s_a.grip.0 * 0.2 + twitch * 0.2 + twitch2 * 0.2,
233                ) * Quaternion::rotation_y(
234                    -0.4 + s_a.grip.0 * 0.2 + move1abs * -2.0,
235                ) * Quaternion::rotation_z(move1abs * 0.5);
236
237                next.chest.position = Vec3::new(
238                    0.0,
239                    s_a.chest.0,
240                    s_a.chest.1 + move1abs * 6.0 + twitch2 + move2abs * 3.0,
241                );
242                next.control_l.orientation = Quaternion::rotation_x(PI / 2.0)
243                    * Quaternion::rotation_y(-0.3)
244                    * Quaternion::rotation_z(-0.3);
245                next.control_l.orientation = Quaternion::rotation_x(PI / 2.0)
246                    * Quaternion::rotation_y(-0.3)
247                    * Quaternion::rotation_z(0.3);
248                next.control.orientation = Quaternion::rotation_x(-0.3)
249                    * Quaternion::rotation_y(0.0)
250                    * Quaternion::rotation_z(0.5 + move1abs * 1.0);
251                next.chest.orientation = Quaternion::rotation_x(0.0) * Quaternion::rotation_z(0.0);
252                next.head.orientation =
253                    Quaternion::rotation_z(twitch * 0.2 + twitch2 * 0.4 + move2abs * -0.5)
254                        * Quaternion::rotation_x(move2abs * 0.4);
255            },
256            _ => {
257                next.chest.orientation = Quaternion::rotation_x(move2abs * -1.0)
258                    * Quaternion::rotation_z(move1 * 1.2 + move2 * -1.8);
259                next.hand_l.position = Vec3::new(-s_a.hand.0, s_a.hand.1, s_a.hand.2);
260                next.hand_l.orientation = Quaternion::rotation_x(1.2);
261                next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1, s_a.hand.2);
262                next.hand_r.orientation = Quaternion::rotation_x(1.2);
263            },
264        }
265        next
266    }
267}