veloren_voxygen_anim/biped_large/
shockwave.rs

1use super::{
2    super::{Animation, vek::*},
3    BipedLargeSkeleton, SkeletonAttr,
4};
5use common::{
6    comp::item::{AbilitySpec, ToolKind},
7    states::utils::StageSection,
8};
9use core::f32::consts::PI;
10
11pub struct ShockwaveAnimation;
12
13type ShockwaveAnimationDependency<'a> = (
14    Option<ToolKind>,
15    (Option<ToolKind>, Option<&'a AbilitySpec>),
16    f32,
17    f32,
18    Option<StageSection>,
19    Option<&'a str>,
20);
21impl Animation for ShockwaveAnimation {
22    type Dependency<'a> = ShockwaveAnimationDependency<'a>;
23    type Skeleton = BipedLargeSkeleton;
24
25    #[cfg(feature = "use-dyn-lib")]
26    const UPDATE_FN: &'static [u8] = b"biped_large_shockwave\0";
27
28    #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_large_shockwave")]
29    #[expect(clippy::single_match)] // TODO: Pending review in #587
30    fn update_skeleton_inner(
31        skeleton: &Self::Skeleton,
32        (
33            active_tool_kind,
34            _second_tool_kind,
35            _global_time,
36            velocity,
37            stage_section,
38            ability_id,
39        ): Self::Dependency<'_>,
40        anim_time: f32,
41        rate: &mut f32,
42        s_a: &SkeletonAttr,
43    ) -> Self::Skeleton {
44        *rate = 1.0;
45        let mut next = (*skeleton).clone();
46
47        let (move1, move1pow, move2, move3) = match stage_section {
48            Some(StageSection::Buildup) => (anim_time, anim_time.powf(0.25), 0.0, 0.0),
49            Some(StageSection::Action) => (1.0, 1.0, anim_time, 0.0),
50            Some(StageSection::Recover) => (1.0, 1.0, 1.0, anim_time),
51            _ => (0.0, 0.0, 0.0, 0.0),
52        };
53
54        let pullback = 1.0 - move3;
55        let move1pow = move1pow * pullback;
56        let move2 = move2 * pullback;
57
58        next.main.position = Vec3::new(0.0, 0.0, 0.0);
59        next.main.orientation = Quaternion::rotation_x(0.0);
60
61        next.hand_l.position = Vec3::new(0.0, 0.0, s_a.grip.0);
62        next.hand_r.position = Vec3::new(0.0, 0.0, s_a.grip.0);
63
64        next.hand_l.orientation = Quaternion::rotation_x(0.0);
65        next.hand_r.orientation = Quaternion::rotation_x(0.0);
66
67        match active_tool_kind {
68            Some(ToolKind::Sceptre | ToolKind::Staff) => {
69                next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
70
71                next.hand_l.position = Vec3::new(s_a.sthl.0, s_a.sthl.1, s_a.sthl.2);
72                next.hand_l.orientation =
73                    Quaternion::rotation_x(s_a.sthl.3) * Quaternion::rotation_y(s_a.sthl.4);
74                next.hand_r.position = Vec3::new(s_a.sthr.0, s_a.sthr.1, s_a.sthr.2);
75                next.hand_r.orientation =
76                    Quaternion::rotation_x(s_a.sthr.3) * Quaternion::rotation_y(s_a.sthr.4);
77                next.main.position = Vec3::new(0.0, 0.0, 0.0);
78                next.main.orientation = Quaternion::rotation_y(0.0);
79
80                next.control.position = Vec3::new(s_a.stc.0, s_a.stc.1, s_a.stc.2);
81                next.control.orientation =
82                    Quaternion::rotation_x(s_a.stc.3) * Quaternion::rotation_y(s_a.stc.4);
83
84                let twist = move1 * 0.8;
85
86                next.control.position = Vec3::new(
87                    s_a.stc.0 + move1 * 5.0 + move3 * -5.0,
88                    s_a.stc.1 + move1 * 13.0 + move3 * -3.0,
89                    s_a.stc.2 + move1 * 10.0 + move2 * -2.0 + move3 * -8.0,
90                );
91                next.control.orientation =
92                    Quaternion::rotation_x(s_a.stc.3 + move1 * 0.8 + move2 * 0.3 + move3 * -1.1)
93                        * Quaternion::rotation_y(
94                            s_a.stc.4 + move1 * -0.15 + move2 * 0.3 + move3 * -0.45,
95                        )
96                        * Quaternion::rotation_z(move1 * 0.8 + move2 * -0.8);
97
98                next.head.orientation = Quaternion::rotation_x(move1 * 0.4 + move3 * -0.4)
99                    * Quaternion::rotation_z(twist * 0.2 + move2 * -0.8 + move3 * 0.6);
100
101                next.upper_torso.position = Vec3::new(
102                    0.0,
103                    s_a.upper_torso.0,
104                    s_a.upper_torso.1 + move1 * 2.0 + move2 * -4.0 + move3 * 2.0,
105                );
106                next.upper_torso.orientation = Quaternion::rotation_x(move2 * -0.8 + move3 * 0.8)
107                    * Quaternion::rotation_z(twist * -0.2 + move2 * -0.1 + move3 * 0.3);
108
109                next.lower_torso.orientation = Quaternion::rotation_x(move2 * 0.3 + move3 * -0.3)
110                    * Quaternion::rotation_z(twist + move2 * -0.8);
111
112                if velocity < 0.5 {
113                    next.foot_l.position = Vec3::new(
114                        -s_a.foot.0,
115                        s_a.foot.1 + move1 * -7.0 + move2 * 7.0,
116                        s_a.foot.2,
117                    );
118                    next.foot_l.orientation = Quaternion::rotation_x(move1 * -0.8 + move2 * 0.8)
119                        * Quaternion::rotation_z(move1 * 0.3 + move2 * -0.3);
120
121                    next.foot_r.position = Vec3::new(
122                        s_a.foot.0,
123                        s_a.foot.1 + move1 * 5.0 + move2 * -5.0,
124                        s_a.foot.2,
125                    );
126                    next.foot_r.orientation = Quaternion::rotation_y(move1 * -0.3 + move2 * 0.3)
127                        * Quaternion::rotation_z(move1 * 0.4 + move2 * -0.4);
128                }
129            },
130            Some(ToolKind::Natural) => match ability_id {
131                Some("common.abilities.custom.yeti.icespikes") => {
132                    next.second.scale = Vec3::one() * 0.0;
133
134                    next.head.orientation = Quaternion::rotation_x(move1pow * 0.8 + move2 * -1.2);
135                    next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
136                    next.jaw.orientation = Quaternion::rotation_x(move2 * -0.3);
137                    next.control_l.position = Vec3::new(-0.5, 4.0, 1.0);
138                    next.control_r.position = Vec3::new(-0.5, 4.0, 1.0);
139                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0);
140                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.0);
141                    next.weapon_l.position =
142                        Vec3::new(-12.0 + (move1pow * 20.0).min(10.0), -1.0, -15.0);
143                    next.weapon_r.position =
144                        Vec3::new(12.0 + (move1pow * -20.0).max(-10.0), -1.0, -15.0);
145
146                    next.weapon_l.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1)
147                        * Quaternion::rotation_z(move1pow * -1.0);
148                    next.weapon_r.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1)
149                        * Quaternion::rotation_z(move1pow * 1.0);
150
151                    next.shoulder_l.orientation =
152                        Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8);
153
154                    next.shoulder_r.orientation =
155                        Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8);
156
157                    next.control.orientation =
158                        Quaternion::rotation_x(move1pow * 2.5 + move2 * -2.0);
159
160                    let twist = move1 * 0.6 + move3 * -0.6;
161                    next.upper_torso.position =
162                        Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1);
163                    next.upper_torso.orientation =
164                        Quaternion::rotation_x(move1pow * 0.8 + move2 * -1.1)
165                            * Quaternion::rotation_z(twist * -0.2 + move1 * -0.1 + move2 * 0.3);
166
167                    next.lower_torso.orientation =
168                        Quaternion::rotation_x(move1pow * -0.8 + move2 * 1.1)
169                            * Quaternion::rotation_z(twist);
170
171                    next.foot_l.position = Vec3::new(
172                        -s_a.foot.0,
173                        s_a.foot.1 + move1pow * -7.0 + move2 * 7.0,
174                        s_a.foot.2,
175                    );
176                    next.foot_l.orientation = Quaternion::rotation_x(move1pow * -0.8 + move2 * 0.8)
177                        * Quaternion::rotation_z(move1pow * 0.3 + move2 * -0.3);
178
179                    next.foot_r.position = Vec3::new(
180                        s_a.foot.0,
181                        s_a.foot.1 + move1pow * 5.0 + move2 * -5.0,
182                        s_a.foot.2,
183                    );
184                    next.foot_r.orientation = Quaternion::rotation_y(move1pow * -0.3 + move2 * 0.3)
185                        * Quaternion::rotation_z(move1pow * 0.4 + move2 * -0.4);
186
187                    next.main.orientation = Quaternion::rotation_y(move1 * 0.4 + move2 * -0.6)
188                        * Quaternion::rotation_x(move2 * -0.4);
189                },
190                _ => {},
191            },
192            Some(ToolKind::Axe) => match ability_id {
193                Some("common.abilities.custom.gigas_frost.flashfreeze") => {
194                    next.second.scale = Vec3::one() * 0.0;
195
196                    next.head.orientation = Quaternion::rotation_x(move1pow * 0.8 + move2 * -1.2);
197                    next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
198                    next.jaw.orientation = Quaternion::rotation_x(move2 * -0.3);
199                    next.control_l.position = Vec3::new(-0.5, 4.0, 1.0);
200                    next.control_r.position = Vec3::new(-0.5, 4.0, 1.0);
201                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0);
202                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.0);
203                    next.weapon_l.position =
204                        Vec3::new(-12.0 + (move1pow * 20.0).min(10.0), -1.0, -15.0);
205                    next.weapon_r.position =
206                        Vec3::new(12.0 + (move1pow * -20.0).max(-10.0), -1.0, -15.0);
207
208                    next.weapon_l.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1)
209                        * Quaternion::rotation_z(move1pow * -1.0);
210                    next.weapon_r.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1)
211                        * Quaternion::rotation_z(move1pow * 1.0);
212
213                    next.shoulder_l.orientation =
214                        Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8);
215
216                    next.shoulder_r.orientation =
217                        Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8);
218
219                    next.control.orientation = Quaternion::rotation_x(move1pow * 1.5 + move2 * 0.6);
220
221                    let twist = move1 * 0.6 + move3 * -0.6;
222                    next.upper_torso.position =
223                        Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1);
224                    next.upper_torso.orientation =
225                        Quaternion::rotation_x(move1pow * 0.4 + move2 * -1.1)
226                            * Quaternion::rotation_z(twist * -0.2 + move1 * -0.1 + move2 * 0.3);
227
228                    next.lower_torso.orientation =
229                        Quaternion::rotation_x(move1pow * -0.4 + move2 * 1.1)
230                            * Quaternion::rotation_z(twist);
231
232                    next.foot_l.position = Vec3::new(
233                        -s_a.foot.0,
234                        s_a.foot.1 + move1pow * -7.0 + move2 * 7.0,
235                        s_a.foot.2,
236                    );
237                    next.foot_l.orientation = Quaternion::rotation_x(move1pow * -0.8 + move2 * 0.8)
238                        * Quaternion::rotation_z(move1pow * 0.3 + move2 * -0.3);
239
240                    next.foot_r.position = Vec3::new(
241                        s_a.foot.0,
242                        s_a.foot.1 + move1pow * 5.0 + move2 * -5.0,
243                        s_a.foot.2,
244                    );
245                    next.foot_r.orientation = Quaternion::rotation_y(move1pow * -0.3 + move2 * 0.3)
246                        * Quaternion::rotation_z(move1pow * 0.4 + move2 * -0.4);
247                    next.main.position = Vec3::new(-5.0 + (move1pow * 20.0).min(10.0), 4.0, 12.0);
248                    next.main.orientation = Quaternion::rotation_y(move1 * 0.4 + move2 * -0.1)
249                        * Quaternion::rotation_x(PI);
250                },
251                _ => {},
252            },
253            Some(ToolKind::Hammer) => match ability_id {
254                Some("common.abilities.custom.cyclops.hammer_shockwave") => {
255                    next.second.scale = Vec3::one() * 0.0;
256
257                    next.head.orientation = Quaternion::rotation_x(move1pow * 0.8 + move2 * -1.2);
258                    next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
259                    next.jaw.orientation = Quaternion::rotation_x(move2 * -0.3);
260                    next.control_l.position = Vec3::new(-0.5, 4.0, 1.0);
261                    next.control_r.position = Vec3::new(-0.5, 4.0, 1.0);
262                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0);
263                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.0);
264                    next.weapon_l.position =
265                        Vec3::new(-12.0 + (move1pow * 20.0).min(10.0), -1.0, -15.0);
266                    next.weapon_r.position =
267                        Vec3::new(12.0 + (move1pow * -20.0).max(-10.0), -1.0, -15.0);
268
269                    next.weapon_l.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1)
270                        * Quaternion::rotation_z(move1pow * -1.0);
271                    next.weapon_r.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1)
272                        * Quaternion::rotation_z(move1pow * 1.0);
273
274                    next.shoulder_l.orientation =
275                        Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8);
276
277                    next.shoulder_r.orientation =
278                        Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8);
279
280                    next.control.orientation =
281                        Quaternion::rotation_x(move1pow * 2.5 + move2 * -2.0);
282
283                    let twist = move1 * 0.6 + move3 * -0.6;
284                    next.upper_torso.position =
285                        Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1);
286                    next.upper_torso.orientation =
287                        Quaternion::rotation_x(move1pow * 0.8 + move2 * -1.1)
288                            * Quaternion::rotation_z(twist * -0.2 + move1 * -0.1 + move2 * 0.3);
289
290                    next.lower_torso.orientation =
291                        Quaternion::rotation_x(move1pow * -0.8 + move2 * 1.1)
292                            * Quaternion::rotation_z(twist);
293
294                    next.foot_l.position = Vec3::new(
295                        -s_a.foot.0,
296                        s_a.foot.1 + move1pow * -7.0 + move2 * 7.0,
297                        s_a.foot.2,
298                    );
299                    next.foot_l.orientation = Quaternion::rotation_x(move1pow * -0.8 + move2 * 0.8)
300                        * Quaternion::rotation_z(move1pow * 0.3 + move2 * -0.3);
301
302                    next.foot_r.position = Vec3::new(
303                        s_a.foot.0,
304                        s_a.foot.1 + move1pow * 5.0 + move2 * -5.0,
305                        s_a.foot.2,
306                    );
307                    next.foot_r.orientation = Quaternion::rotation_y(move1pow * -0.3 + move2 * 0.3)
308                        * Quaternion::rotation_z(move1pow * 0.4 + move2 * -0.4);
309
310                    next.main.orientation = Quaternion::rotation_y(move1 * 0.4 + move2 * -0.6)
311                        * Quaternion::rotation_x(move2 * -0.4);
312                },
313                Some("common.abilities.custom.dwarves.forgemaster.lavawave") => {
314                    next.head.orientation = Quaternion::rotation_x(move1pow * 0.8 + move2 * -1.2);
315                    next.control_l.position = Vec3::new(-0.5, 8.0, 1.0);
316                    next.control_r.position = Vec3::new(-0.5, 8.0, 1.0);
317                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0);
318                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.0);
319                    next.weapon_l.position =
320                        Vec3::new(-12.0 + (move1pow * 20.0).min(10.0), 3.0, -25.0);
321                    next.weapon_r.position =
322                        Vec3::new(12.0 + (move1pow * -20.0).max(-10.0), 3.0, -25.0);
323
324                    next.weapon_l.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1)
325                        * Quaternion::rotation_z(move1pow * -1.0);
326                    next.weapon_r.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1)
327                        * Quaternion::rotation_z(move1pow * 1.0);
328
329                    next.shoulder_l.orientation =
330                        Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8);
331
332                    next.shoulder_r.orientation =
333                        Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8);
334
335                    next.control.orientation =
336                        Quaternion::rotation_x(move1pow * 2.5 + move2 * -2.0);
337
338                    let twist = move1 * 0.6 + move3 * -0.6;
339                    next.upper_torso.position =
340                        Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1);
341                    next.upper_torso.orientation =
342                        Quaternion::rotation_x(move1pow * 0.8 + move2 * -1.1)
343                            * Quaternion::rotation_z(twist * -0.2 + move1 * -0.1 + move2 * 0.3);
344
345                    next.lower_torso.orientation =
346                        Quaternion::rotation_x(move1pow * -0.8 + move2 * 1.1)
347                            * Quaternion::rotation_z(twist);
348
349                    next.foot_l.position = Vec3::new(
350                        -s_a.foot.0,
351                        s_a.foot.1 + move1pow * -7.0 + move2 * 7.0,
352                        s_a.foot.2,
353                    );
354                    next.foot_l.orientation = Quaternion::rotation_x(move1pow * -0.8 + move2 * 0.8)
355                        * Quaternion::rotation_z(move1pow * 0.3 + move2 * -0.3);
356
357                    next.foot_r.position = Vec3::new(
358                        s_a.foot.0,
359                        s_a.foot.1 + move1pow * 5.0 + move2 * -5.0,
360                        s_a.foot.2,
361                    );
362                    next.foot_r.orientation = Quaternion::rotation_y(move1pow * -0.3 + move2 * 0.3)
363                        * Quaternion::rotation_z(move1pow * 0.4 + move2 * -0.4);
364
365                    next.main.orientation = Quaternion::rotation_y(move1 * 0.4 + move2 * -0.6)
366                        * Quaternion::rotation_x(move2 * -0.4)
367                        * Quaternion::rotation_z(0.8);
368                },
369                _ => {},
370            },
371            _ => {},
372        }
373        next
374    }
375}