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 BeamAnimation;
12
13impl Animation for BeamAnimation {
14 type Dependency<'a> = (
15 Option<ToolKind>,
16 (Option<ToolKind>, Option<&'a AbilitySpec>),
17 f32,
18 Vec3<f32>,
19 Option<StageSection>,
20 f32,
21 f32,
22 Option<&'a str>,
23 );
24 type Skeleton = BipedLargeSkeleton;
25
26 #[cfg(feature = "use-dyn-lib")]
27 const UPDATE_FN: &'static [u8] = b"biped_large_beam\0";
28
29 #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_large_beam")]
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 acc_vel,
39 timer,
40 ability_id,
41 ): Self::Dependency<'_>,
42 anim_time: f32,
43 rate: &mut f32,
44 s_a: &SkeletonAttr,
45 ) -> Self::Skeleton {
46 *rate = 1.0;
47 let mut next = (*skeleton).clone();
48
49 let speed = Vec2::<f32>::from(velocity).magnitude();
50
51 let lab: f32 = 0.65 * s_a.tempo;
52 let speednorm = (speed / 12.0).powf(0.4);
53 let foothoril = (acc_vel * lab + PI * 1.45).sin() * speednorm;
54 let foothorir = (acc_vel * lab + PI * (0.45)).sin() * speednorm;
55 let footrotl = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 1.4).sin()).powi(2))).sqrt())
56 * ((acc_vel * lab + PI * 1.4).sin())
57 * speednorm;
58
59 let footrotr = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 0.4).sin()).powi(2))).sqrt())
60 * ((acc_vel * lab + PI * 0.4).sin())
61 * speednorm;
62 let subtract = global_time - timer;
63 let check = subtract - subtract.trunc();
64 let mirror = (check - 0.5).signum();
65 next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
66 next.jaw.orientation = Quaternion::rotation_x(0.0);
67
68 next.main.position = Vec3::new(0.0, 0.0, 0.0);
69 next.main.orientation = Quaternion::rotation_x(0.0);
70
71 next.hand_l.position = Vec3::new(s_a.grip.1, 0.0, s_a.grip.0);
72 next.hand_r.position = Vec3::new(-s_a.grip.1, 0.0, s_a.grip.0);
73
74 next.hand_l.orientation = Quaternion::rotation_x(0.0);
75 next.hand_r.orientation = Quaternion::rotation_x(0.0);
76 let (move1base, move2shake, move2base, move3) = match stage_section {
77 Some(StageSection::Buildup) => ((anim_time.powf(0.25)).min(1.0), 0.0, 0.0, 0.0),
78 Some(StageSection::Action) => (
79 1.0,
80 (anim_time * 15.0 + PI).sin(),
81 (anim_time.powf(0.1)).min(1.0),
82 0.0,
83 ),
84 Some(StageSection::Recover) => (1.0, 1.0, 1.0, anim_time),
85 _ => (0.0, 0.0, 0.0, 0.0),
86 };
87 let pullback = 1.0 - move3;
88 let move1 = move1base * pullback;
89 let move2 = move2base * pullback;
90 match active_tool_kind {
91 Some(ToolKind::Staff) => {
92 next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
93 next.control_r.position =
94 Vec3::new(1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
95
96 next.control.position = Vec3::new(
97 -3.0 + move1 * -5.0,
98 3.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
99 -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
100 );
101 next.head.orientation =
102 Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
103 next.jaw.orientation = Quaternion::rotation_x(0.0);
104
105 next.control_l.orientation =
106 Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
107 next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.4)
108 * Quaternion::rotation_y(0.5)
109 * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
110
111 next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
112 * Quaternion::rotation_y(-0.1 + move1 * 0.6);
113 next.shoulder_l.position = Vec3::new(
114 -s_a.shoulder.0,
115 s_a.shoulder.1,
116 s_a.shoulder.2 - foothorir * 1.0,
117 );
118 next.shoulder_l.orientation =
119 Quaternion::rotation_x(move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2));
120 next.shoulder_r.position = Vec3::new(
121 s_a.shoulder.0,
122 s_a.shoulder.1,
123 s_a.shoulder.2 - foothoril * 1.0,
124 );
125 next.shoulder_r.orientation =
126 Quaternion::rotation_x(move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2));
127 },
128 Some(ToolKind::Sceptre) => match ability_id {
129 Some("common.abilities.custom.sea_bishop.longbeam") => {
130 next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
131 next.control_r.position =
132 Vec3::new(-1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
133
134 next.control.position = Vec3::new(
135 -3.0 + move1 * -5.0,
136 -2.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
137 -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
138 );
139 next.head.orientation =
140 Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
141 next.jaw.orientation = Quaternion::rotation_x(0.0);
142
143 next.control_l.orientation =
144 Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
145 next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.4)
146 * Quaternion::rotation_y(0.5)
147 * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
148
149 next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
150 * Quaternion::rotation_y(-0.1 + move1 * 0.6);
151 next.shoulder_l.position = Vec3::new(
152 -s_a.shoulder.0,
153 s_a.shoulder.1,
154 s_a.shoulder.2 - foothorir * 1.0,
155 );
156 next.shoulder_l.orientation = Quaternion::rotation_x(
157 move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2),
158 );
159 next.shoulder_r.position = Vec3::new(
160 s_a.shoulder.0,
161 s_a.shoulder.1,
162 s_a.shoulder.2 - foothoril * 1.0,
163 );
164 next.shoulder_r.orientation = Quaternion::rotation_x(
165 move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2),
166 );
167 },
168 _ => {
169 next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
170 next.control_r.position =
171 Vec3::new(1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
172
173 next.control.position = Vec3::new(
174 -3.0 + move1 * -5.0,
175 3.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
176 -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
177 );
178 next.head.orientation =
179 Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
180 next.jaw.orientation = Quaternion::rotation_x(0.0);
181
182 next.control_l.orientation =
183 Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
184 next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.4)
185 * Quaternion::rotation_y(0.5)
186 * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
187
188 next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
189 * Quaternion::rotation_y(-0.1 + move1 * 0.6);
190 next.shoulder_l.position = Vec3::new(
191 -s_a.shoulder.0,
192 s_a.shoulder.1,
193 s_a.shoulder.2 - foothorir * 1.0,
194 );
195 next.shoulder_l.orientation = Quaternion::rotation_x(
196 move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2),
197 );
198 next.shoulder_r.position = Vec3::new(
199 s_a.shoulder.0,
200 s_a.shoulder.1,
201 s_a.shoulder.2 - foothoril * 1.0,
202 );
203 next.shoulder_r.orientation = Quaternion::rotation_x(
204 move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2),
205 );
206 },
207 },
208 Some(ToolKind::Hammer) => match ability_id {
209 Some("common.abilities.custom.dwarves.forgemaster.flamethrower") => {
210 next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
211 next.control_r.position =
212 Vec3::new(-1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
213
214 next.control.position = Vec3::new(
215 -3.0 + move1 * -5.0,
216 -2.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
217 -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
218 );
219 next.head.orientation =
220 Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
221 next.jaw.orientation = Quaternion::rotation_x(0.0);
222
223 next.control_l.orientation =
224 Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
225 next.control_r.orientation = Quaternion::rotation_x(move1 * 0.4)
226 * Quaternion::rotation_y(0.8)
227 * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
228
229 next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
230 * Quaternion::rotation_y(-0.1 + move1 * 0.3);
231 next.shoulder_l.position = Vec3::new(
232 -s_a.shoulder.0,
233 s_a.shoulder.1,
234 s_a.shoulder.2 - foothorir * 1.0,
235 );
236 next.shoulder_l.orientation = Quaternion::rotation_x(
237 move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2),
238 );
239 next.shoulder_r.position = Vec3::new(
240 s_a.shoulder.0,
241 s_a.shoulder.1,
242 s_a.shoulder.2 - foothoril * 1.0,
243 );
244 next.shoulder_r.orientation = Quaternion::rotation_x(
245 move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2),
246 );
247 },
248 _ => {
249 next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
250 next.control_r.position =
251 Vec3::new(1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
252
253 next.control.position = Vec3::new(
254 -3.0 + move1 * -5.0,
255 3.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
256 -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
257 );
258 next.head.orientation =
259 Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
260 next.jaw.orientation = Quaternion::rotation_x(0.0);
261
262 next.control_l.orientation =
263 Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
264 next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.4)
265 * Quaternion::rotation_y(0.5)
266 * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
267
268 next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
269 * Quaternion::rotation_y(-0.1 + move1 * 0.6);
270 next.shoulder_l.position = Vec3::new(
271 -s_a.shoulder.0,
272 s_a.shoulder.1,
273 s_a.shoulder.2 - foothorir * 1.0,
274 );
275 next.shoulder_l.orientation = Quaternion::rotation_x(
276 move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2),
277 );
278 next.shoulder_r.position = Vec3::new(
279 s_a.shoulder.0,
280 s_a.shoulder.1,
281 s_a.shoulder.2 - foothoril * 1.0,
282 );
283 next.shoulder_r.orientation = Quaternion::rotation_x(
284 move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2),
285 );
286 },
287 },
288 Some(ToolKind::Natural) => match ability_id {
289 Some("common.abilities.custom.tidalwarrior.bubbles") => {
290 if mirror > 0.0 {
291 next.head.orientation = Quaternion::rotation_z(move1 * -0.6);
292 next.upper_torso.orientation = Quaternion::rotation_z(move1 * 0.6);
293 next.lower_torso.orientation = Quaternion::rotation_z(move1 * -0.6);
294
295 next.shoulder_l.orientation = Quaternion::rotation_z(move1 * 0.3);
296 next.hand_l.position = Vec3::new(-14.0 + move1 * 3.0, 2.0, -4.0);
297
298 next.hand_l.orientation =
299 Quaternion::rotation_x(PI / 3.0 + move2shake * -0.07)
300 * Quaternion::rotation_y(move1 * -0.5)
301 * Quaternion::rotation_z(-0.35 + move2shake * 0.07);
302 next.hand_r.position = Vec3::new(14.0 + move1 - 3.0, 2.0, -4.0);
303
304 next.hand_r.orientation =
305 Quaternion::rotation_x(PI / 3.0 + move2shake * 0.07)
306 * Quaternion::rotation_y(move1 * -0.5)
307 * Quaternion::rotation_z(0.35 - move2shake * 0.07);
308
309 next.shoulder_r.orientation = Quaternion::rotation_z(move1 * -0.3);
310 } else {
311 next.head.orientation = Quaternion::rotation_z(move1 * 0.6);
312 next.upper_torso.orientation = Quaternion::rotation_z(move1 * -0.6);
313 next.lower_torso.orientation = Quaternion::rotation_z(move1 * 0.6);
314
315 next.shoulder_l.orientation = Quaternion::rotation_z(move1 * -0.3);
316 next.hand_l.position = Vec3::new(-14.0 + move1 * 3.0, 2.0, -4.0);
317
318 next.hand_l.orientation =
319 Quaternion::rotation_x(PI / 3.0 + move2shake * 0.07)
320 * Quaternion::rotation_y(move1 * 0.5)
321 * Quaternion::rotation_z(-0.35 + move2shake * 0.07);
322 next.hand_r.position = Vec3::new(14.0 + move1 - 3.0, 2.0, -4.0);
323
324 next.hand_r.orientation =
325 Quaternion::rotation_x(PI / 3.0 + move2shake * -0.07)
326 * Quaternion::rotation_y(move1 * 0.5)
327 * Quaternion::rotation_z(0.35 - move2shake * -0.07);
328
329 next.shoulder_r.orientation = Quaternion::rotation_z(move1 * 0.3);
330 };
331 },
332 Some("common.abilities.custom.yeti.frostbreath") => {
333 next.second.scale = Vec3::one() * 0.0;
334
335 next.head.orientation =
336 Quaternion::rotation_x(move1 * 0.5 + move2 * -0.5 + move2shake * -0.02);
337 next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
338 next.jaw.orientation = Quaternion::rotation_x(move2 * -0.5 + move2shake * -0.1);
339 next.control_l.position = Vec3::new(-0.5, 4.0, 1.0);
340 next.control_r.position = Vec3::new(-0.5, 4.0, 1.0);
341 next.control_l.orientation = Quaternion::rotation_x(PI / 2.0);
342 next.control_r.orientation = Quaternion::rotation_x(PI / 2.0);
343
344 next.weapon_l.position = Vec3::new(-12.0, -1.0, -15.0);
345 next.weapon_r.position = Vec3::new(12.0, -1.0, -15.0);
346
347 next.weapon_l.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1);
348 next.weapon_r.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1);
349
350 next.arm_control_r.orientation =
351 Quaternion::rotation_x(move1 * 1.1 + move2 * -1.6)
352 * Quaternion::rotation_y(move1 * 1.4 + move2 * -1.8);
353
354 next.shoulder_l.orientation =
355 Quaternion::rotation_x(move1 * 1.4 + move2 * -1.8);
356
357 next.shoulder_r.orientation =
358 Quaternion::rotation_x(move1 * 1.4 + move2 * -1.8);
359
360 next.upper_torso.position = Vec3::new(
361 0.0,
362 s_a.upper_torso.0,
363 s_a.upper_torso.1 + move1 * -1.9 + move2 * 1.2,
364 );
365 next.upper_torso.orientation =
366 Quaternion::rotation_x(move1 * 0.8 + move2 * -1.1 + move2shake * -0.02);
367 next.lower_torso.position =
368 Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1);
369 next.lower_torso.orientation =
370 Quaternion::rotation_x(move1 * -0.8 + move2 * 1.1 + move2shake * 0.02);
371 },
372 Some("common.abilities.custom.harvester.firebreath") => {
373 next.head.orientation =
374 Quaternion::rotation_x(move1 * 0.5 + move2 * -0.4 + move2shake * -0.02);
375
376 next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
377 next.jaw.orientation = Quaternion::rotation_x(move2 * -0.5 + move2shake * -0.1);
378
379 next.upper_torso.position = Vec3::new(
380 0.0,
381 s_a.upper_torso.0 + move1 * -3.0 + move2 * 3.0,
382 s_a.upper_torso.1 + move1 * -0.4,
383 );
384 next.upper_torso.orientation =
385 Quaternion::rotation_x(move1 * 0.8 + move2 * -1.1 + move2shake * -0.02);
386 next.lower_torso.position =
387 Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1);
388 next.lower_torso.orientation =
389 Quaternion::rotation_x(move1 * -0.8 + move2 * 1.1 + move2shake * 0.02);
390
391 next.control_l.position = Vec3::new(1.0, 2.0, 8.0);
392 next.control_r.position = Vec3::new(1.0, 1.0, -2.0);
393
394 next.control.position =
395 Vec3::new(-6.0, 0.0 + s_a.grip.0 / 1.0, -s_a.grip.0 / 0.8);
396
397 next.control_l.orientation =
398 Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_z(PI);
399 next.control_r.orientation =
400 Quaternion::rotation_x(PI / 2.0 + 0.2) * Quaternion::rotation_y(-1.0);
401
402 next.control.orientation =
403 Quaternion::rotation_x(-1.4) * Quaternion::rotation_y(-2.8);
404
405 next.weapon_l.position = Vec3::new(move1 * 8.0, move1 * 1.0, move1 * 6.0);
406 next.weapon_l.orientation =
407 Quaternion::rotation_x(move1 * 0.5) * Quaternion::rotation_y(move1 * -0.8);
408
409 next.shoulder_l.position = Vec3::new(
410 -s_a.shoulder.0,
411 s_a.shoulder.1,
412 s_a.shoulder.2 - foothorir * 1.0,
413 );
414 next.shoulder_l.orientation = Quaternion::rotation_y(-0.4 + move1 * 0.8)
415 * Quaternion::rotation_x(-0.4 + move1 * -0.2);
416 next.shoulder_r.orientation = Quaternion::rotation_y(0.4 + move1 * -0.8)
417 * Quaternion::rotation_x(0.4 + move1 * -0.8);
418
419 next.hand_r.position = Vec3::new(
420 -s_a.grip.1 + move1 * -5.0,
421 0.0 + move1 * 6.0,
422 s_a.grip.0 + move1 * 13.0,
423 );
424 next.hand_r.orientation = Quaternion::rotation_x(move1 * -3.0)
425 * Quaternion::rotation_y(move1 * 1.5)
426 * Quaternion::rotation_z(move1 * -1.5);
427 },
428 _ => {},
429 },
430 _ => {},
431 }
432
433 next
434 }
435}