1use super::{
2 super::{Animation, vek::*},
3 CharacterSkeleton, SkeletonAttr,
4};
5use common::comp::item::{AbilitySpec, Hands, ToolKind};
6use core::f32::consts::PI;
7
8pub struct WallrunAnimation;
9
10impl Animation for WallrunAnimation {
11 type Dependency<'a> = (
12 (Option<ToolKind>, Option<&'a AbilitySpec>),
13 Option<ToolKind>,
14 (Option<Hands>, Option<Hands>),
15 Vec3<f32>,
16 f32,
17 Option<Vec3<f32>>,
18 bool,
19 );
20 type Skeleton = CharacterSkeleton;
21
22 #[cfg(feature = "use-dyn-lib")]
23 const UPDATE_FN: &'static [u8] = b"character_wallrun\0";
24
25 #[cfg_attr(feature = "be-dyn-lib", export_name = "character_wallrun")]
26
27 fn update_skeleton_inner(
28 skeleton: &Self::Skeleton,
29 (
30 (active_tool_kind, active_tool_spec),
31 second_tool_kind,
32 hands,
33 orientation,
34 acc_vel,
35 wall,
36 was_wielded,
37 ): Self::Dependency<'_>,
38 _anim_time: f32,
39 rate: &mut f32,
40 s_a: &SkeletonAttr,
41 ) -> Self::Skeleton {
42 let mut next = (*skeleton).clone();
43
44 *rate = 1.0;
45
46 let lab: f32 = 0.8;
47
48 let footrotl = ((1.0 / (0.5 + (0.5) * ((acc_vel * 1.6 * lab + PI * 1.4).sin()).powi(2)))
49 .sqrt())
50 * ((acc_vel * 1.6 * lab + PI * 1.4).sin());
51 let footrotr = ((1.0 / (0.5 + (0.5) * ((acc_vel * 1.6 * lab + PI * 0.4).sin()).powi(2)))
52 .sqrt())
53 * ((acc_vel * 1.6 * lab + PI * 0.4).sin());
54
55 let foothoril = (acc_vel * 2.2 * lab + PI * 1.45).sin();
56 let foothorir = (acc_vel * 2.2 * lab + PI * (0.45)).sin();
57
58 let shortalt = (acc_vel * lab * 2.2 + PI / 1.0).sin();
59
60 let short = ((5.0 / (1.5 + 3.5 * ((acc_vel * lab * 1.6).sin()).powi(2))).sqrt())
61 * ((acc_vel * lab * 1.6).sin());
62
63 next.shorts.position = Vec3::new(0.0, s_a.shorts.0 + 2.0, s_a.shorts.1 + 1.0);
64 next.belt.position = Vec3::new(0.0, s_a.belt.0 + 1.0, s_a.belt.1);
65
66 next.foot_l.position = Vec3::new(
67 -s_a.foot.0,
68 s_a.foot.1 + foothorir * 6.0,
69 s_a.foot.2 + shortalt * 2.0 + 2.0,
70 );
71 next.foot_l.orientation = Quaternion::rotation_x(0.6 + shortalt * 0.8);
72
73 next.foot_r.position = Vec3::new(
74 s_a.foot.0,
75 s_a.foot.1 + foothoril * 6.0,
76 s_a.foot.2 + shortalt * -2.0 + 2.0,
77 );
78 next.foot_r.orientation = Quaternion::rotation_x(0.6 - shortalt * 0.8);
79 next.belt.orientation = Quaternion::rotation_x(0.3);
80 next.shorts.orientation = Quaternion::rotation_x(0.5);
81
82 next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + shortalt * 0.0);
83
84 next.shoulder_l.orientation = Quaternion::rotation_x(short * 0.15);
85
86 next.shoulder_r.orientation = Quaternion::rotation_x(short * -0.15);
87
88 if wall.is_some_and(|e| e.y > 0.5) {
89 let push = (1.0 - orientation.x.abs()).powi(2);
90 let right_sub = -(orientation.x).min(0.0);
91 let left_sub = (orientation.x).max(0.0);
92 next.hand_l.position = Vec3::new(
93 -s_a.hand.0,
94 s_a.hand.1,
95 s_a.hand.2 + push * 5.0 + 2.0 * left_sub,
96 );
97 next.hand_r.position = Vec3::new(
98 s_a.hand.0,
99 s_a.hand.1,
100 s_a.hand.2 + push * 5.0 + 2.0 * right_sub,
101 );
102 next.hand_l.orientation =
103 Quaternion::rotation_x(push * 2.0 + footrotr * -0.2 * right_sub)
104 * Quaternion::rotation_y(1.0 * left_sub)
105 * Quaternion::rotation_z(2.5 * left_sub + 1.0 * right_sub);
106 next.hand_r.orientation =
107 Quaternion::rotation_x(push * 2.0 + footrotl * -0.2 * left_sub)
108 * Quaternion::rotation_y(-1.0 * right_sub)
109 * Quaternion::rotation_z(-2.5 * right_sub - 1.0 * left_sub);
110 next.torso.orientation = Quaternion::rotation_y(orientation.x / 1.5);
111 next.chest.orientation = Quaternion::rotation_y(orientation.x / -3.0)
112 * Quaternion::rotation_z(shortalt * -0.2);
113 next.head.orientation = Quaternion::rotation_z(shortalt * 0.25)
114 * Quaternion::rotation_z(orientation.x / -2.0)
115 * Quaternion::rotation_x(-0.1);
116 } else if wall.is_some_and(|e| e.y < -0.5) {
117 let push = (1.0 - orientation.x.abs()).powi(2);
118 let right_sub = (orientation.x).max(0.0);
119 let left_sub = -(orientation.x).min(0.0);
120 next.hand_l.position = Vec3::new(
121 -s_a.hand.0,
122 s_a.hand.1,
123 s_a.hand.2 + push * 5.0 + 2.0 * left_sub,
124 );
125 next.hand_r.position = Vec3::new(
126 s_a.hand.0,
127 s_a.hand.1,
128 s_a.hand.2 + push * 5.0 + 2.0 * right_sub,
129 );
130 next.hand_l.orientation =
131 Quaternion::rotation_x(push * 2.0 + footrotr * -0.2 * right_sub)
132 * Quaternion::rotation_y(1.0 * left_sub)
133 * Quaternion::rotation_z(2.5 * left_sub + 1.0 * right_sub);
134 next.hand_r.orientation =
135 Quaternion::rotation_x(push * 2.0 + footrotl * -0.2 * left_sub)
136 * Quaternion::rotation_y(-1.0 * right_sub)
137 * Quaternion::rotation_z(-2.5 * right_sub - 1.0 * left_sub);
138 next.chest.orientation = Quaternion::rotation_y(orientation.x);
139 next.torso.orientation = Quaternion::rotation_y(orientation.x / -1.5);
140 next.chest.orientation = Quaternion::rotation_y(orientation.x / 3.0)
141 * Quaternion::rotation_z(shortalt * -0.2);
142 next.head.orientation = Quaternion::rotation_z(shortalt * 0.25)
143 * Quaternion::rotation_z(orientation.x / 2.0)
144 * Quaternion::rotation_x(-0.1);
145 } else if wall.is_some_and(|e| e.x < -0.5) {
146 let push = (1.0 - orientation.y.abs()).powi(2);
147 let right_sub = -(orientation.y).min(0.0);
148 let left_sub = (orientation.y).max(0.0);
149 next.hand_l.position = Vec3::new(
150 -s_a.hand.0,
151 s_a.hand.1,
152 s_a.hand.2 + push * 5.0 + 2.0 * left_sub,
153 );
154 next.hand_r.position = Vec3::new(
155 s_a.hand.0,
156 s_a.hand.1,
157 s_a.hand.2 + push * 5.0 + 2.0 * right_sub,
158 );
159 next.hand_l.orientation =
160 Quaternion::rotation_x(push * 2.0 + footrotr * -0.2 * right_sub)
161 * Quaternion::rotation_y(1.0 * left_sub)
162 * Quaternion::rotation_z(2.5 * left_sub + 1.0 * right_sub);
163 next.hand_r.orientation =
164 Quaternion::rotation_x(push * 2.0 + footrotl * -0.2 * left_sub)
165 * Quaternion::rotation_y(-1.0 * right_sub)
166 * Quaternion::rotation_z(-2.5 * right_sub - 1.0 * left_sub);
167 next.torso.orientation = Quaternion::rotation_y(orientation.y / 1.5);
168 next.chest.orientation = Quaternion::rotation_y(orientation.y / -3.0)
169 * Quaternion::rotation_z(shortalt * -0.2);
170 next.head.orientation = Quaternion::rotation_z(shortalt * 0.25)
171 * Quaternion::rotation_z(orientation.y / -2.0)
172 * Quaternion::rotation_x(-0.1);
173 } else if wall.is_some_and(|e| e.x > 0.5) {
174 let push = (1.0 - orientation.y.abs()).powi(2);
175 let right_sub = (orientation.y).max(0.0);
176 let left_sub = -(orientation.y).min(0.0);
177 next.hand_l.position = Vec3::new(
178 -s_a.hand.0,
179 s_a.hand.1,
180 s_a.hand.2 + push * 5.0 + 2.0 * left_sub,
181 );
182 next.hand_r.position = Vec3::new(
183 s_a.hand.0,
184 s_a.hand.1,
185 s_a.hand.2 + push * 5.0 + 2.0 * right_sub,
186 );
187 next.hand_l.orientation =
188 Quaternion::rotation_x(push * 2.0 + footrotr * -0.2 * right_sub)
189 * Quaternion::rotation_y(1.0 * left_sub)
190 * Quaternion::rotation_z(2.5 * left_sub + 1.0 * right_sub);
191 next.hand_r.orientation =
192 Quaternion::rotation_x(push * 2.0 + footrotl * -0.2 * left_sub)
193 * Quaternion::rotation_y(-1.0 * right_sub)
194 * Quaternion::rotation_z(-2.5 * right_sub - 1.0 * left_sub);
195 next.torso.orientation = Quaternion::rotation_y(orientation.y / -1.5);
196 next.chest.orientation = Quaternion::rotation_y(orientation.y / 3.0)
197 * Quaternion::rotation_z(shortalt * -0.2);
198 next.head.orientation = Quaternion::rotation_z(shortalt * 0.25)
199 * Quaternion::rotation_z(orientation.y / 2.0)
200 * Quaternion::rotation_x(-0.1);
201 };
202
203 if was_wielded {
204 next.main.position = Vec3::new(0.0, 0.0, 0.0);
205 next.main.orientation = Quaternion::rotation_x(0.0);
206 next.second.position = Vec3::new(0.0, 0.0, 0.0);
207 next.second.orientation = Quaternion::rotation_x(0.0);
208 next.hold.scale = Vec3::one() * 0.0;
209
210 match (hands, active_tool_kind, second_tool_kind) {
211 ((Some(Hands::Two), _), tool, _) | ((None, Some(Hands::Two)), _, tool) => {
212 match tool {
213 Some(ToolKind::Sword) => {
214 next.hand_l.position = Vec3::new(s_a.shl.0, s_a.shl.1, s_a.shl.2);
215 next.hand_l.orientation = Quaternion::rotation_x(s_a.shl.3)
216 * Quaternion::rotation_y(s_a.shl.4);
217 next.hand_r.position = Vec3::new(s_a.shr.0, s_a.shr.1, s_a.shr.2);
218 next.hand_r.orientation = Quaternion::rotation_x(s_a.shr.3)
219 * Quaternion::rotation_y(s_a.shr.4);
220
221 next.control.position = Vec3::new(s_a.sc.0, s_a.sc.1 - 3.0, s_a.sc.2);
222 next.control.orientation =
223 Quaternion::rotation_x(s_a.sc.3) * Quaternion::rotation_z(0.0);
224 },
225 Some(ToolKind::Axe) => {
226 next.main.position = Vec3::new(0.0, 0.0, 0.0);
227 next.main.orientation = Quaternion::rotation_x(0.0);
228
229 next.hand_l.position = Vec3::new(s_a.ahl.0, s_a.ahl.1, s_a.ahl.2);
230 next.hand_l.orientation = Quaternion::rotation_x(s_a.ahl.3)
231 * Quaternion::rotation_y(s_a.ahl.4);
232 next.hand_r.position = Vec3::new(s_a.ahr.0, s_a.ahr.1, s_a.ahr.2);
233 next.hand_r.orientation = Quaternion::rotation_x(s_a.ahr.3)
234 * Quaternion::rotation_z(s_a.ahr.5);
235
236 next.control.position = Vec3::new(s_a.ac.0, s_a.ac.1, s_a.ac.2);
237 next.control.orientation = Quaternion::rotation_x(s_a.ac.3)
238 * Quaternion::rotation_y(s_a.ac.4)
239 * Quaternion::rotation_z(s_a.ac.5);
240 },
241 Some(ToolKind::Hammer | ToolKind::Pick | ToolKind::Shovel) => {
242 next.hand_l.position = Vec3::new(s_a.hhl.0, s_a.hhl.1, s_a.hhl.2);
243 next.hand_l.orientation = Quaternion::rotation_x(s_a.hhl.3)
244 * Quaternion::rotation_y(s_a.hhl.4)
245 * Quaternion::rotation_z(s_a.hhl.5);
246 next.hand_r.position = Vec3::new(s_a.hhr.0, s_a.hhr.1, s_a.hhr.2);
247 next.hand_r.orientation = Quaternion::rotation_x(s_a.hhr.3)
248 * Quaternion::rotation_y(s_a.hhr.4)
249 * Quaternion::rotation_z(s_a.hhr.5);
250
251 next.control.position = Vec3::new(s_a.hc.0, s_a.hc.1, s_a.hc.2 + 6.0);
252 next.control.orientation = Quaternion::rotation_x(s_a.hc.3)
253 * Quaternion::rotation_y(s_a.hc.4)
254 * Quaternion::rotation_z(s_a.hc.5);
255 },
256 Some(ToolKind::Staff) | Some(ToolKind::Sceptre) => {
257 next.hand_r.position = Vec3::new(s_a.sthr.0, s_a.sthr.1, s_a.sthr.2);
258 next.hand_r.orientation = Quaternion::rotation_x(s_a.sthr.3)
259 * Quaternion::rotation_y(s_a.sthr.4);
260
261 next.control.position =
262 Vec3::new(s_a.stc.0, s_a.stc.1 - 2.0, s_a.stc.2 + 4.0);
263
264 next.hand_l.position = Vec3::new(s_a.sthl.0, s_a.sthl.1, s_a.sthl.2);
265 next.hand_l.orientation = Quaternion::rotation_x(s_a.sthl.3);
266
267 next.control.orientation = Quaternion::rotation_x(s_a.stc.3)
268 * Quaternion::rotation_y(s_a.stc.4)
269 * Quaternion::rotation_z(s_a.stc.5);
270 },
271 Some(ToolKind::Bow) => {
272 next.main.position = Vec3::new(0.0, 0.0, 0.0);
273 next.main.orientation = Quaternion::rotation_x(0.0);
274 next.hand_l.position = Vec3::new(s_a.bhl.0, s_a.bhl.1, s_a.bhl.2);
275 next.hand_l.orientation = Quaternion::rotation_x(s_a.bhl.3);
276 next.hand_r.position = Vec3::new(s_a.bhr.0, s_a.bhr.1, s_a.bhr.2);
277 next.hand_r.orientation = Quaternion::rotation_x(s_a.bhr.3);
278
279 next.hold.position = Vec3::new(0.0, -1.0, -5.2);
280 next.hold.orientation = Quaternion::rotation_x(-PI / 2.0);
281 next.hold.scale = Vec3::one() * 1.0;
282
283 next.control.position =
284 Vec3::new(s_a.bc.0 + 2.0, s_a.bc.1, s_a.bc.2 + 5.0);
285 next.control.orientation = Quaternion::rotation_x(0.8)
286 * Quaternion::rotation_y(s_a.bc.4)
287 * Quaternion::rotation_z(s_a.bc.5);
288 },
289 Some(ToolKind::Instrument) => {
290 if let Some(AbilitySpec::Custom(spec)) = active_tool_spec {
291 match spec.as_str() {
292 "Washboard" => {
293 next.hand_l.position = Vec3::new(-7.0, 0.0, 3.0);
294 next.hand_l.orientation = Quaternion::rotation_x(1.27);
295 next.main.position = Vec3::new(-5.0, -4.5, -5.0);
296 next.main.orientation = Quaternion::rotation_x(5.5);
297 },
298 _ => {
299 next.hand_l.position = Vec3::new(-7.0, 4.0, 3.0);
300 next.hand_l.orientation = Quaternion::rotation_x(1.27);
301 next.main.position = Vec3::new(-5.0, 5.0, 23.0);
302 next.main.orientation = Quaternion::rotation_x(PI);
303 },
304 }
305 }
306 },
307 Some(ToolKind::Debug) => {
308 next.hand_l.position = Vec3::new(-7.0, 4.0, 3.0);
309 next.hand_l.orientation = Quaternion::rotation_x(1.27);
310 next.main.position = Vec3::new(-5.0, 5.0, 23.0);
311 next.main.orientation = Quaternion::rotation_x(PI);
312 },
313 Some(ToolKind::Farming) => {
314 next.head.orientation = Quaternion::rotation_x(-0.2);
315 next.hand_l.position = Vec3::new(9.0, 1.0, 1.0);
316 next.hand_l.orientation = Quaternion::rotation_x(PI / 2.0);
317 next.hand_r.position = Vec3::new(9.0, 1.0, 11.0);
318 next.hand_r.orientation = Quaternion::rotation_x(PI / 2.0);
319 next.main.position = Vec3::new(7.5, 7.5, 13.2);
320 next.main.orientation = Quaternion::rotation_y(PI);
321
322 next.control.position = Vec3::new(-11.0, 1.8, 4.0);
323 next.control.orientation = Quaternion::rotation_x(0.0)
324 * Quaternion::rotation_y(0.6)
325 * Quaternion::rotation_z(0.0);
326 },
327 _ => {},
328 }
329 },
330 ((_, _), _, _) => {},
331 };
332 match hands {
333 (Some(Hands::One), _) => {
334 next.control_l.position = Vec3::new(-7.0, 6.0, 5.0);
335 next.control_l.orientation =
336 Quaternion::rotation_x(-0.3) * Quaternion::rotation_y(0.2);
337 next.hand_l.position = Vec3::new(-1.0, -0.5, 0.0);
338 next.hand_l.orientation = Quaternion::rotation_x(PI / 2.0)
339 },
340 (_, _) => {},
341 };
342 match hands {
343 (None | Some(Hands::One), Some(Hands::One)) => {
344 next.control_r.position = Vec3::new(7.0, 6.0, 5.0);
345 next.control_r.orientation =
346 Quaternion::rotation_x(-0.3) * Quaternion::rotation_y(-0.2);
347 next.hand_r.position = Vec3::new(1.0, -0.5, 0.0);
348 next.hand_r.orientation = Quaternion::rotation_x(PI / 2.0)
349 },
350 (_, _) => {},
351 };
352 match hands {
353 (None, None) | (None, Some(Hands::One)) => {
354 next.hand_l.position = Vec3::new(-8.0, 2.0, 1.0);
355 next.hand_l.orientation =
356 Quaternion::rotation_x(0.5) * Quaternion::rotation_y(0.25);
357 },
358 (_, _) => {},
359 };
360 match hands {
361 (None, None) | (Some(Hands::One), None) => {
362 next.hand_r.position = Vec3::new(8.0, 2.0, 1.0);
363 next.hand_r.orientation =
364 Quaternion::rotation_x(0.5) * Quaternion::rotation_y(-0.25);
365 },
366 (_, _) => {},
367 };
368 }
369
370 next
371 }
372}