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}